Wed, 24 Aug 2005 17:10:20 +0000
[gaim-migrate @ 13546]
Remove // comments
| 10684 | 1 | /* |
| 2 | * gaim | |
| 3 | * | |
| 4 | * Gaim 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 | * Original md5 | |
| 9 | * Copyright (C) 2001-2003 Christophe Devine <c.devine@cr0.net> | |
| 10 | * | |
|
11329
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
11 | * Original md4 taken from linux kernel |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
12 | * MD4 Message Digest Algorithm (RFC1320). |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
13 | * |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
14 | * Implementation derived from Andrew Tridgell and Steve French's |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
15 | * CIFS MD4 implementation, and the cryptoapi implementation |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
16 | * originally based on the public domain implementation written |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
17 | * by Colin Plumb in 1993. |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
18 | * |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
19 | * Copyright (c) Andrew Tridgell 1997-1998. |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
20 | * Modified by Steve French (sfrench@us.ibm.com) 2002 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
21 | * Copyright (c) Cryptoapi developers. |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
22 | * Copyright (c) 2002 David S. Miller (davem@redhat.com) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
23 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
24 | * |
| 10684 | 25 | * This program is free software; you can redistribute it and/or modify |
| 26 | * it under the terms of the GNU General Public License as published by | |
| 27 | * the Free Software Foundation; either version 2 of the License, or | |
| 28 | * (at your option) any later version. | |
| 29 | * | |
| 30 | * This program is distributed in the hope that it will be useful, | |
| 31 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 32 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 33 | * GNU General Public License for more details. | |
| 34 | * | |
| 35 | * You should have received a copy of the GNU General Public License | |
| 36 | * along with this program; if not, write to the Free Software | |
| 37 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 38 | */ | |
| 39 | #include <glib.h> | |
| 40 | #include <string.h> | |
| 41 | #include <stdio.h> | |
| 42 | ||
| 43 | #include "internal.h" | |
| 44 | #include "cipher.h" | |
| 45 | #include "debug.h" | |
| 46 | #include "signals.h" | |
| 47 | #include "value.h" | |
| 48 | ||
| 49 | /******************************************************************************* | |
| 50 | * MD5 | |
| 51 | ******************************************************************************/ | |
| 52 | struct MD5Context { | |
| 53 | guint32 total[2]; | |
| 54 | guint32 state[4]; | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
55 | guchar buffer[64]; |
| 10684 | 56 | }; |
| 57 | ||
| 58 | #define MD5_GET_GUINT32(n,b,i) { \ | |
| 59 | (n) = ((guint32)(b) [(i) ] ) \ | |
| 60 | | ((guint32)(b) [(i) + 1] << 8) \ | |
| 61 | | ((guint32)(b) [(i) + 2] << 16) \ | |
| 62 | | ((guint32)(b) [(i) + 3] << 24); \ | |
| 63 | } | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
64 | #define MD5_PUT_GUINT32(n,b,i) { \ |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
65 | (b)[(i) ] = (guchar)((n) ); \ |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
66 | (b)[(i) + 1] = (guchar)((n) >> 8); \ |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
67 | (b)[(i) + 2] = (guchar)((n) >> 16); \ |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
68 | (b)[(i) + 3] = (guchar)((n) >> 24); \ |
| 10684 | 69 | } |
| 70 | ||
| 71 | static void | |
| 72 | md5_init(GaimCipherContext *context, gpointer extra) { | |
| 73 | struct MD5Context *md5_context; | |
| 74 | ||
| 75 | md5_context = g_new0(struct MD5Context, 1); | |
| 76 | ||
| 77 | gaim_cipher_context_set_data(context, md5_context); | |
| 78 | ||
| 79 | gaim_cipher_context_reset(context, extra); | |
| 80 | } | |
| 81 | ||
| 82 | static void | |
| 83 | md5_reset(GaimCipherContext *context, gpointer extra) { | |
| 84 | struct MD5Context *md5_context; | |
| 85 | ||
| 86 | md5_context = gaim_cipher_context_get_data(context); | |
| 87 | ||
| 88 | md5_context->total[0] = 0; | |
| 89 | md5_context->total[1] = 0; | |
| 90 | ||
| 91 | md5_context->state[0] = 0x67452301; | |
| 92 | md5_context->state[1] = 0xEFCDAB89; | |
| 93 | md5_context->state[2] = 0x98BADCFE; | |
| 94 | md5_context->state[3] = 0x10325476; | |
| 95 | ||
| 96 | memset(md5_context->buffer, 0, sizeof(md5_context->buffer)); | |
| 97 | } | |
| 98 | ||
| 99 | static void | |
| 100 | md5_uninit(GaimCipherContext *context) { | |
| 101 | struct MD5Context *md5_context; | |
| 102 | ||
| 103 | gaim_cipher_context_reset(context, NULL); | |
| 104 | ||
| 105 | md5_context = gaim_cipher_context_get_data(context); | |
| 106 | memset(md5_context, 0, sizeof(md5_context)); | |
| 107 | ||
| 108 | g_free(md5_context); | |
| 109 | md5_context = NULL; | |
| 110 | } | |
| 111 | ||
| 112 | static void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
113 | md5_process(struct MD5Context *md5_context, const guchar data[64]) { |
| 10684 | 114 | guint32 X[16], A, B, C, D; |
| 115 | ||
| 116 | A = md5_context->state[0]; | |
| 117 | B = md5_context->state[1]; | |
| 118 | C = md5_context->state[2]; | |
| 119 | D = md5_context->state[3]; | |
| 120 | ||
| 121 | MD5_GET_GUINT32(X[ 0], data, 0); | |
| 122 | MD5_GET_GUINT32(X[ 1], data, 4); | |
| 123 | MD5_GET_GUINT32(X[ 2], data, 8); | |
| 124 | MD5_GET_GUINT32(X[ 3], data, 12); | |
| 125 | MD5_GET_GUINT32(X[ 4], data, 16); | |
| 126 | MD5_GET_GUINT32(X[ 5], data, 20); | |
| 127 | MD5_GET_GUINT32(X[ 6], data, 24); | |
| 128 | MD5_GET_GUINT32(X[ 7], data, 28); | |
| 129 | MD5_GET_GUINT32(X[ 8], data, 32); | |
| 130 | MD5_GET_GUINT32(X[ 9], data, 36); | |
| 131 | MD5_GET_GUINT32(X[10], data, 40); | |
| 132 | MD5_GET_GUINT32(X[11], data, 44); | |
| 133 | MD5_GET_GUINT32(X[12], data, 48); | |
| 134 | MD5_GET_GUINT32(X[13], data, 52); | |
| 135 | MD5_GET_GUINT32(X[14], data, 56); | |
| 136 | MD5_GET_GUINT32(X[15], data, 60); | |
| 137 | ||
| 138 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) | |
| 139 | #define P(a,b,c,d,k,s,t) { \ | |
| 140 | a += F(b,c,d) + X[k] + t; \ | |
| 141 | a = S(a,s) + b; \ | |
| 142 | } | |
| 143 | ||
| 144 | /* first pass */ | |
| 145 | #define F(x,y,z) (z ^ (x & (y ^ z))) | |
| 146 | P(A, B, C, D, 0, 7, 0xD76AA478); | |
| 147 | P(D, A, B, C, 1, 12, 0xE8C7B756); | |
| 148 | P(C, D, A, B, 2, 17, 0x242070DB); | |
| 149 | P(B, C, D, A, 3, 22, 0xC1BDCEEE); | |
| 150 | P(A, B, C, D, 4, 7, 0xF57C0FAF); | |
| 151 | P(D, A, B, C, 5, 12, 0x4787C62A); | |
| 152 | P(C, D, A, B, 6, 17, 0xA8304613); | |
| 153 | P(B, C, D, A, 7, 22, 0xFD469501); | |
| 154 | P(A, B, C, D, 8, 7, 0x698098D8); | |
| 155 | P(D, A, B, C, 9, 12, 0x8B44F7AF); | |
| 156 | P(C, D, A, B, 10, 17, 0xFFFF5BB1); | |
| 157 | P(B, C, D, A, 11, 22, 0x895CD7BE); | |
| 158 | P(A, B, C, D, 12, 7, 0x6B901122); | |
| 159 | P(D, A, B, C, 13, 12, 0xFD987193); | |
| 160 | P(C, D, A, B, 14, 17, 0xA679438E); | |
| 161 | P(B, C, D, A, 15, 22, 0x49B40821); | |
| 162 | #undef F | |
| 163 | ||
| 164 | /* second pass */ | |
| 165 | #define F(x,y,z) (y ^ (z & (x ^ y))) | |
| 166 | P(A, B, C, D, 1, 5, 0xF61E2562); | |
| 167 | P(D, A, B, C, 6, 9, 0xC040B340); | |
| 168 | P(C, D, A, B, 11, 14, 0x265E5A51); | |
| 169 | P(B, C, D, A, 0, 20, 0xE9B6C7AA); | |
| 170 | P(A, B, C, D, 5, 5, 0xD62F105D); | |
| 171 | P(D, A, B, C, 10, 9, 0x02441453); | |
| 172 | P(C, D, A, B, 15, 14, 0xD8A1E681); | |
| 173 | P(B, C, D, A, 4, 20, 0xE7D3FBC8); | |
| 174 | P(A, B, C, D, 9, 5, 0x21E1CDE6); | |
| 175 | P(D, A, B, C, 14, 9, 0xC33707D6); | |
| 176 | P(C, D, A, B, 3, 14, 0xF4D50D87); | |
| 177 | P(B, C, D, A, 8, 20, 0x455A14ED); | |
| 178 | P(A, B, C, D, 13, 5, 0xA9E3E905); | |
| 179 | P(D, A, B, C, 2, 9, 0xFCEFA3F8); | |
| 180 | P(C, D, A, B, 7, 14, 0x676F02D9); | |
| 181 | P(B, C, D, A, 12, 20, 0x8D2A4C8A); | |
| 182 | #undef F | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
183 | |
| 10684 | 184 | /* third pass */ |
| 185 | #define F(x,y,z) (x ^ y ^ z) | |
| 186 | P(A, B, C, D, 5, 4, 0xFFFA3942); | |
| 187 | P(D, A, B, C, 8, 11, 0x8771F681); | |
| 188 | P(C, D, A, B, 11, 16, 0x6D9D6122); | |
| 189 | P(B, C, D, A, 14, 23, 0xFDE5380C); | |
| 190 | P(A, B, C, D, 1, 4, 0xA4BEEA44); | |
| 191 | P(D, A, B, C, 4, 11, 0x4BDECFA9); | |
| 192 | P(C, D, A, B, 7, 16, 0xF6BB4B60); | |
| 193 | P(B, C, D, A, 10, 23, 0xBEBFBC70); | |
| 194 | P(A, B, C, D, 13, 4, 0x289B7EC6); | |
| 195 | P(D, A, B, C, 0, 11, 0xEAA127FA); | |
| 196 | P(C, D, A, B, 3, 16, 0xD4EF3085); | |
| 197 | P(B, C, D, A, 6, 23, 0x04881D05); | |
| 198 | P(A, B, C, D, 9, 4, 0xD9D4D039); | |
| 199 | P(D, A, B, C, 12, 11, 0xE6DB99E5); | |
| 200 | P(C, D, A, B, 15, 16, 0x1FA27CF8); | |
| 201 | P(B, C, D, A, 2, 23, 0xC4AC5665); | |
| 202 | #undef F | |
| 203 | ||
| 204 | /* forth pass */ | |
| 205 | #define F(x,y,z) (y ^ (x | ~z)) | |
| 206 | P(A, B, C, D, 0, 6, 0xF4292244); | |
| 207 | P(D, A, B, C, 7, 10, 0x432AFF97); | |
| 208 | P(C, D, A, B, 14, 15, 0xAB9423A7); | |
| 209 | P(B, C, D, A, 5, 21, 0xFC93A039); | |
| 210 | P(A, B, C, D, 12, 6, 0x655B59C3); | |
| 211 | P(D, A, B, C, 3, 10, 0x8F0CCC92); | |
| 212 | P(C, D, A, B, 10, 15, 0xFFEFF47D); | |
| 213 | P(B, C, D, A, 1, 21, 0x85845DD1); | |
| 214 | P(A, B, C, D, 8, 6, 0x6FA87E4F); | |
| 215 | P(D, A, B, C, 15, 10, 0xFE2CE6E0); | |
| 216 | P(C, D, A, B, 6, 15, 0xA3014314); | |
| 217 | P(B, C, D, A, 13, 21, 0x4E0811A1); | |
| 218 | P(A, B, C, D, 4, 6, 0xF7537E82); | |
| 219 | P(D, A, B, C, 11, 10, 0xBD3AF235); | |
| 220 | P(C, D, A, B, 2, 15, 0x2AD7D2BB); | |
| 221 | P(B, C, D, A, 9, 21, 0xEB86D391); | |
| 222 | #undef F | |
| 223 | #undef P | |
| 224 | #undef S | |
| 225 | ||
| 226 | md5_context->state[0] += A; | |
| 227 | md5_context->state[1] += B; | |
| 228 | md5_context->state[2] += C; | |
| 229 | md5_context->state[3] += D; | |
| 230 | } | |
| 231 | ||
| 232 | static void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
233 | md5_append(GaimCipherContext *context, const guchar *data, size_t len) { |
| 10684 | 234 | struct MD5Context *md5_context = NULL; |
| 235 | guint32 left = 0, fill = 0; | |
| 236 | ||
| 237 | g_return_if_fail(context != NULL); | |
| 238 | ||
| 239 | md5_context = gaim_cipher_context_get_data(context); | |
| 240 | g_return_if_fail(md5_context != NULL); | |
| 241 | ||
| 242 | left = md5_context->total[0] & 0x3F; | |
| 243 | fill = 64 - left; | |
| 244 | ||
| 245 | md5_context->total[0] += len; | |
| 246 | md5_context->total[0] &= 0xFFFFFFFF; | |
| 247 | ||
| 248 | if(md5_context->total[0] < len) | |
| 249 | md5_context->total[1]++; | |
| 250 | ||
| 251 | if(left && len >= fill) { | |
| 252 | memcpy((md5_context->buffer + left), data, fill); | |
| 253 | md5_process(md5_context, md5_context->buffer); | |
| 254 | len -= fill; | |
| 255 | data += fill; | |
| 256 | left = 0; | |
| 257 | } | |
| 258 | ||
| 259 | while(len >= 64) { | |
| 260 | md5_process(md5_context, data); | |
| 261 | len -= 64; | |
| 262 | data += 64; | |
| 263 | } | |
| 264 | ||
| 265 | if(len) { | |
| 266 | memcpy((md5_context->buffer + left), data, len); | |
| 267 | } | |
| 268 | } | |
| 269 | ||
| 270 | static gboolean | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
271 | md5_digest(GaimCipherContext *context, size_t in_len, guchar digest[16], |
| 10687 | 272 | size_t *out_len) |
| 273 | { | |
| 10684 | 274 | struct MD5Context *md5_context = NULL; |
| 275 | guint32 last, pad; | |
| 276 | guint32 high, low; | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
277 | guchar message[8]; |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
278 | guchar padding[64] = { |
| 10684 | 279 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 280 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 281 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 282 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
| 283 | }; | |
| 284 | ||
| 10687 | 285 | g_return_val_if_fail(in_len >= 16, FALSE); |
| 10684 | 286 | |
| 287 | md5_context = gaim_cipher_context_get_data(context); | |
| 288 | ||
| 289 | high = (md5_context->total[0] >> 29) | |
| 290 | | (md5_context->total[1] << 3); | |
| 291 | low = (md5_context->total[0] << 3); | |
| 292 | ||
| 293 | MD5_PUT_GUINT32(low, message, 0); | |
| 294 | MD5_PUT_GUINT32(high, message, 4); | |
| 295 | ||
| 296 | last = md5_context->total[0] & 0x3F; | |
| 297 | pad = (last < 56) ? (56 - last) : (120 - last); | |
| 298 | ||
| 299 | md5_append(context, padding, pad); | |
| 300 | md5_append(context, message, 8); | |
| 301 | ||
| 302 | MD5_PUT_GUINT32(md5_context->state[0], digest, 0); | |
| 303 | MD5_PUT_GUINT32(md5_context->state[1], digest, 4); | |
| 304 | MD5_PUT_GUINT32(md5_context->state[2], digest, 8); | |
| 305 | MD5_PUT_GUINT32(md5_context->state[3], digest, 12); | |
| 306 | ||
| 10687 | 307 | if(out_len) |
| 308 | *out_len = 16; | |
| 309 | ||
| 10684 | 310 | return TRUE; |
| 311 | } | |
| 312 | ||
| 313 | static GaimCipherOps MD5Ops = { | |
| 314 | NULL, /* Set option */ | |
| 315 | NULL, /* Get option */ | |
| 316 | md5_init, /* init */ | |
| 317 | md5_reset, /* reset */ | |
| 318 | md5_uninit, /* uninit */ | |
| 319 | NULL, /* set iv */ | |
| 320 | md5_append, /* append */ | |
| 321 | md5_digest, /* digest */ | |
| 322 | NULL, /* encrypt */ | |
| 323 | NULL, /* decrypt */ | |
| 324 | NULL, /* set salt */ | |
| 325 | NULL, /* get salt size */ | |
| 326 | NULL, /* set key */ | |
| 327 | NULL /* get key size */ | |
| 328 | }; | |
| 329 | ||
| 330 | /******************************************************************************* | |
|
11329
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
331 | * MD4 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
332 | ******************************************************************************/ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
333 | #define MD4_DIGEST_SIZE 16 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
334 | #define MD4_HMAC_BLOCK_SIZE 64 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
335 | #define MD4_BLOCK_WORDS 16 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
336 | #define MD4_HASH_WORDS 4 |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
337 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
338 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
339 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
340 | struct MD4_Context { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
341 | guint32 hash[MD4_HASH_WORDS]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
342 | guint32 block[MD4_BLOCK_WORDS]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
343 | guint64 byte_count; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
344 | }; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
345 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
346 | static inline guint32 lshift(guint32 x, unsigned int s) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
347 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
348 | x &= 0xFFFFFFFF; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
349 | return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
350 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
351 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
352 | static inline guint32 F(guint32 x, guint32 y, guint32 z) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
353 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
354 | return (x & y) | ((~x) & z); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
355 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
356 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
357 | static inline guint32 G(guint32 x, guint32 y, guint32 z) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
358 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
359 | return (x & y) | (x & z) | (y & z); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
360 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
361 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
362 | static inline guint32 H(guint32 x, guint32 y, guint32 z) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
363 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
364 | return x ^ y ^ z; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
365 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
366 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
367 | #define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
368 | #define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (guint32)0x5A827999,s)) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
369 | #define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (guint32)0x6ED9EBA1,s)) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
370 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
371 | static inline void le32_to_cpu_array(guint32 *buf, unsigned int words) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
372 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
373 | while (words--) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
374 | *buf=GUINT_FROM_LE(*buf); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
375 | buf++; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
376 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
377 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
378 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
379 | static inline void cpu_to_le32_array(guint32 *buf, unsigned int words) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
380 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
381 | while (words--) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
382 | *buf=GUINT_TO_LE(*buf); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
383 | buf++; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
384 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
385 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
386 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
387 | static void md4_transform(guint32 *hash, guint32 const *in) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
388 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
389 | guint32 a, b, c, d; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
390 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
391 | a = hash[0]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
392 | b = hash[1]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
393 | c = hash[2]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
394 | d = hash[3]; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
395 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
396 | ROUND1(a, b, c, d, in[0], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
397 | ROUND1(d, a, b, c, in[1], 7); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
398 | ROUND1(c, d, a, b, in[2], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
399 | ROUND1(b, c, d, a, in[3], 19); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
400 | ROUND1(a, b, c, d, in[4], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
401 | ROUND1(d, a, b, c, in[5], 7); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
402 | ROUND1(c, d, a, b, in[6], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
403 | ROUND1(b, c, d, a, in[7], 19); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
404 | ROUND1(a, b, c, d, in[8], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
405 | ROUND1(d, a, b, c, in[9], 7); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
406 | ROUND1(c, d, a, b, in[10], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
407 | ROUND1(b, c, d, a, in[11], 19); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
408 | ROUND1(a, b, c, d, in[12], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
409 | ROUND1(d, a, b, c, in[13], 7); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
410 | ROUND1(c, d, a, b, in[14], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
411 | ROUND1(b, c, d, a, in[15], 19); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
412 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
413 | ROUND2(a, b, c, d,in[ 0], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
414 | ROUND2(d, a, b, c, in[4], 5); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
415 | ROUND2(c, d, a, b, in[8], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
416 | ROUND2(b, c, d, a, in[12], 13); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
417 | ROUND2(a, b, c, d, in[1], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
418 | ROUND2(d, a, b, c, in[5], 5); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
419 | ROUND2(c, d, a, b, in[9], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
420 | ROUND2(b, c, d, a, in[13], 13); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
421 | ROUND2(a, b, c, d, in[2], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
422 | ROUND2(d, a, b, c, in[6], 5); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
423 | ROUND2(c, d, a, b, in[10], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
424 | ROUND2(b, c, d, a, in[14], 13); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
425 | ROUND2(a, b, c, d, in[3], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
426 | ROUND2(d, a, b, c, in[7], 5); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
427 | ROUND2(c, d, a, b, in[11], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
428 | ROUND2(b, c, d, a, in[15], 13); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
429 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
430 | ROUND3(a, b, c, d,in[ 0], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
431 | ROUND3(d, a, b, c, in[8], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
432 | ROUND3(c, d, a, b, in[4], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
433 | ROUND3(b, c, d, a, in[12], 15); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
434 | ROUND3(a, b, c, d, in[2], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
435 | ROUND3(d, a, b, c, in[10], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
436 | ROUND3(c, d, a, b, in[6], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
437 | ROUND3(b, c, d, a, in[14], 15); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
438 | ROUND3(a, b, c, d, in[1], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
439 | ROUND3(d, a, b, c, in[9], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
440 | ROUND3(c, d, a, b, in[5], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
441 | ROUND3(b, c, d, a, in[13], 15); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
442 | ROUND3(a, b, c, d, in[3], 3); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
443 | ROUND3(d, a, b, c, in[11], 9); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
444 | ROUND3(c, d, a, b, in[7], 11); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
445 | ROUND3(b, c, d, a, in[15], 15); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
446 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
447 | hash[0] += a; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
448 | hash[1] += b; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
449 | hash[2] += c; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
450 | hash[3] += d; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
451 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
452 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
453 | static inline void md4_transform_helper(struct MD4_Context *ctx) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
454 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
455 | le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(guint32)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
456 | md4_transform(ctx->hash, ctx->block); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
457 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
458 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
459 | static void |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
460 | md4_init(GaimCipherContext *context, gpointer extra) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
461 | struct MD4_Context *mctx; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
462 | mctx = g_new0(struct MD4_Context, 1); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
463 | gaim_cipher_context_set_data(context, mctx); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
464 | gaim_cipher_context_reset(context, extra); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
465 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
466 | mctx->hash[0] = 0x67452301; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
467 | mctx->hash[1] = 0xefcdab89; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
468 | mctx->hash[2] = 0x98badcfe; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
469 | mctx->hash[3] = 0x10325476; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
470 | mctx->byte_count = 0; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
471 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
472 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
473 | static void |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
474 | md4_reset(GaimCipherContext *context, gpointer extra) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
475 | struct MD4_Context *mctx; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
476 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
477 | mctx = gaim_cipher_context_get_data(context); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
478 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
479 | mctx->hash[0] = 0x67452301; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
480 | mctx->hash[1] = 0xefcdab89; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
481 | mctx->hash[2] = 0x98badcfe; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
482 | mctx->hash[3] = 0x10325476; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
483 | mctx->byte_count = 0; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
484 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
485 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
486 | static void |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
487 | md4_append(GaimCipherContext *context, const guchar *data, size_t len) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
488 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
489 | struct MD4_Context *mctx = gaim_cipher_context_get_data(context); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
490 | const guint32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
491 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
492 | mctx->byte_count += len; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
493 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
494 | if (avail > len) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
495 | memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
496 | data, len); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
497 | return; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
498 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
499 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
500 | memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
501 | data, avail); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
502 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
503 | md4_transform_helper(mctx); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
504 | data += avail; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
505 | len -= avail; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
506 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
507 | while (len >= sizeof(mctx->block)) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
508 | memcpy(mctx->block, data, sizeof(mctx->block)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
509 | md4_transform_helper(mctx); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
510 | data += sizeof(mctx->block); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
511 | len -= sizeof(mctx->block); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
512 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
513 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
514 | memcpy(mctx->block, data, len); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
515 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
516 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
517 | static gboolean |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
518 | md4_digest(GaimCipherContext *context, size_t in_len, guchar *out, |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
519 | size_t *out_len) |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
520 | { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
521 | struct MD4_Context *mctx = gaim_cipher_context_get_data(context); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
522 | const unsigned int offset = mctx->byte_count & 0x3f; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
523 | char *p = (char *)mctx->block + offset; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
524 | int padding = 56 - (offset + 1); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
525 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
526 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
527 | if(in_len<16) return FALSE; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
528 | if(out_len) *out_len = 16; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
529 | *p++ = 0x80; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
530 | if (padding < 0) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
531 | memset(p, 0x00, padding + sizeof (guint64)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
532 | md4_transform_helper(mctx); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
533 | p = (char *)mctx->block; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
534 | padding = 56; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
535 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
536 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
537 | memset(p, 0, padding); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
538 | mctx->block[14] = mctx->byte_count << 3; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
539 | mctx->block[15] = mctx->byte_count >> 29; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
540 | le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
541 | sizeof(guint64)) / sizeof(guint32)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
542 | md4_transform(mctx->hash, mctx->block); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
543 | cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(guint32)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
544 | memcpy(out, mctx->hash, sizeof(mctx->hash)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
545 | memset(mctx, 0, sizeof(*mctx)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
546 | return TRUE; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
547 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
548 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
549 | static void |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
550 | md4_uninit(GaimCipherContext *context) { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
551 | struct MD4_Context *md4_context; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
552 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
553 | gaim_cipher_context_reset(context, NULL); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
554 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
555 | md4_context = gaim_cipher_context_get_data(context); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
556 | memset(md4_context, 0, sizeof(md4_context)); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
557 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
558 | g_free(md4_context); |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
559 | md4_context = NULL; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
560 | } |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
561 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
562 | static GaimCipherOps MD4Ops = { |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
563 | NULL, /* Set option */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
564 | NULL, /* Get option */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
565 | md4_init, /* init */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
566 | md4_reset, /* reset */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
567 | md4_uninit, /* uninit */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
568 | NULL, /* set iv */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
569 | md4_append, /* append */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
570 | md4_digest, /* digest */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
571 | NULL, /* encrypt */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
572 | NULL, /* decrypt */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
573 | NULL, /* set salt */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
574 | NULL, /* get salt size */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
575 | NULL, /* set key */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
576 | NULL /* get key size */ |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
577 | }; |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
578 | |
|
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
579 | /******************************************************************************* |
| 10684 | 580 | * SHA-1 |
| 581 | ******************************************************************************/ | |
| 582 | #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) | |
| 583 | ||
| 584 | struct SHA1Context { | |
| 585 | guint32 H[5]; | |
| 586 | guint32 W[80]; | |
| 587 | ||
| 588 | gint lenW; | |
| 589 | ||
| 590 | guint32 sizeHi; | |
| 591 | guint32 sizeLo; | |
| 592 | }; | |
| 593 | ||
| 594 | static void | |
| 595 | sha1_hash_block(struct SHA1Context *sha1_ctx) { | |
| 596 | gint i; | |
| 597 | guint32 A, B, C, D, E, T; | |
| 598 | ||
| 599 | for(i = 16; i < 80; i++) { | |
| 600 | sha1_ctx->W[i] = SHA1_ROTL(sha1_ctx->W[i - 3] ^ | |
| 601 | sha1_ctx->W[i - 8] ^ | |
| 602 | sha1_ctx->W[i - 14] ^ | |
| 603 | sha1_ctx->W[i - 16], 1); | |
| 604 | } | |
| 605 | ||
| 606 | A = sha1_ctx->H[0]; | |
| 607 | B = sha1_ctx->H[1]; | |
| 608 | C = sha1_ctx->H[2]; | |
| 609 | D = sha1_ctx->H[3]; | |
| 610 | E = sha1_ctx->H[4]; | |
| 611 | ||
| 612 | for(i = 0; i < 20; i++) { | |
| 613 | T = (SHA1_ROTL(A, 5) + (((C ^ D) & B) ^ D) + E + sha1_ctx->W[i] + 0x5A827999) & 0xFFFFFFFF; | |
| 614 | E = D; | |
| 615 | D = C; | |
| 616 | C = SHA1_ROTL(B, 30); | |
| 617 | B = A; | |
| 618 | A = T; | |
| 619 | } | |
| 620 | ||
| 621 | for(i = 20; i < 40; i++) { | |
| 622 | T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0x6ED9EBA1) & 0xFFFFFFFF; | |
| 623 | E = D; | |
| 624 | D = C; | |
| 625 | C = SHA1_ROTL(B, 30); | |
| 626 | B = A; | |
| 627 | A = T; | |
| 628 | } | |
| 629 | ||
| 630 | for(i = 40; i < 60; i++) { | |
| 631 | T = (SHA1_ROTL(A, 5) + ((B & C) | (D & (B | C))) + E + sha1_ctx->W[i] + 0x8F1BBCDC) & 0xFFFFFFFF; | |
| 632 | E = D; | |
| 633 | D = C; | |
| 634 | C = SHA1_ROTL(B, 30); | |
| 635 | B = A; | |
| 636 | A = T; | |
| 637 | } | |
| 638 | ||
| 639 | for(i = 60; i < 80; i++) { | |
| 640 | T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0xCA62C1D6) & 0xFFFFFFFF; | |
| 641 | E = D; | |
| 642 | D = C; | |
| 643 | C = SHA1_ROTL(B, 30); | |
| 644 | B = A; | |
| 645 | A = T; | |
| 646 | } | |
| 647 | ||
| 648 | sha1_ctx->H[0] += A; | |
| 649 | sha1_ctx->H[1] += B; | |
| 650 | sha1_ctx->H[2] += C; | |
| 651 | sha1_ctx->H[3] += D; | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
652 | sha1_ctx->H[4] += E; |
| 10684 | 653 | } |
| 654 | ||
| 655 | static void | |
| 656 | sha1_set_opt(GaimCipherContext *context, const gchar *name, void *value) { | |
| 657 | struct SHA1Context *ctx; | |
| 658 | ||
| 659 | ctx = gaim_cipher_context_get_data(context); | |
| 660 | ||
| 661 | if(!strcmp(name, "sizeHi")) { | |
| 662 | ctx->sizeHi = GPOINTER_TO_INT(value); | |
| 663 | } else if(!strcmp(name, "sizeLo")) { | |
| 664 | ctx->sizeLo = GPOINTER_TO_INT(value); | |
| 665 | } else if(!strcmp(name, "lenW")) { | |
| 666 | ctx->lenW = GPOINTER_TO_INT(value); | |
| 667 | } | |
| 668 | } | |
| 669 | ||
| 670 | static void * | |
| 671 | sha1_get_opt(GaimCipherContext *context, const gchar *name) { | |
| 672 | struct SHA1Context *ctx; | |
| 673 | ||
| 674 | ctx = gaim_cipher_context_get_data(context); | |
| 675 | ||
| 676 | if(!strcmp(name, "sizeHi")) { | |
| 677 | return GINT_TO_POINTER(ctx->sizeHi); | |
| 678 | } else if(!strcmp(name, "sizeLo")) { | |
| 679 | return GINT_TO_POINTER(ctx->sizeLo); | |
| 680 | } else if(!strcmp(name, "lenW")) { | |
| 681 | return GINT_TO_POINTER(ctx->lenW); | |
| 682 | } | |
| 683 | ||
| 684 | return NULL; | |
| 685 | } | |
| 686 | ||
| 687 | static void | |
| 688 | sha1_init(GaimCipherContext *context, void *extra) { | |
| 689 | struct SHA1Context *sha1_ctx; | |
| 690 | ||
| 691 | sha1_ctx = g_new0(struct SHA1Context, 1); | |
| 692 | ||
| 693 | gaim_cipher_context_set_data(context, sha1_ctx); | |
| 694 | ||
| 695 | gaim_cipher_context_reset(context, extra); | |
| 696 | } | |
| 697 | ||
| 698 | static void | |
| 699 | sha1_reset(GaimCipherContext *context, void *extra) { | |
| 700 | struct SHA1Context *sha1_ctx; | |
| 701 | gint i; | |
| 702 | ||
| 703 | sha1_ctx = gaim_cipher_context_get_data(context); | |
| 704 | ||
| 705 | g_return_if_fail(sha1_ctx); | |
| 706 | ||
| 707 | sha1_ctx->lenW = 0; | |
| 708 | sha1_ctx->sizeHi = 0; | |
| 709 | sha1_ctx->sizeLo = 0; | |
| 710 | ||
| 711 | sha1_ctx->H[0] = 0x67452301; | |
| 712 | sha1_ctx->H[1] = 0xEFCDAB89; | |
| 713 | sha1_ctx->H[2] = 0x98BADCFE; | |
| 714 | sha1_ctx->H[3] = 0x10325476; | |
| 715 | sha1_ctx->H[4] = 0xC3D2E1F0; | |
| 716 | ||
| 717 | for(i = 0; i < 80; i++) | |
| 718 | sha1_ctx->W[i] = 0; | |
| 719 | } | |
| 720 | ||
| 721 | static void | |
| 722 | sha1_uninit(GaimCipherContext *context) { | |
| 723 | struct SHA1Context *sha1_ctx; | |
| 724 | ||
| 725 | gaim_cipher_context_reset(context, NULL); | |
| 726 | ||
| 727 | sha1_ctx = gaim_cipher_context_get_data(context); | |
| 728 | ||
| 729 | memset(sha1_ctx, 0, sizeof(struct SHA1Context)); | |
| 730 | ||
| 731 | g_free(sha1_ctx); | |
| 732 | sha1_ctx = NULL; | |
| 733 | } | |
| 734 | ||
| 735 | ||
| 736 | static void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
737 | sha1_append(GaimCipherContext *context, const guchar *data, size_t len) { |
| 10684 | 738 | struct SHA1Context *sha1_ctx; |
| 739 | gint i; | |
| 740 | ||
| 741 | sha1_ctx = gaim_cipher_context_get_data(context); | |
| 742 | ||
| 743 | g_return_if_fail(sha1_ctx); | |
| 744 | ||
| 745 | for(i = 0; i < len; i++) { | |
| 746 | sha1_ctx->W[sha1_ctx->lenW / 4] <<= 8; | |
| 747 | sha1_ctx->W[sha1_ctx->lenW / 4] |= data[i]; | |
| 748 | ||
| 749 | if((++sha1_ctx->lenW) % 64 == 0) { | |
| 750 | sha1_hash_block(sha1_ctx); | |
| 751 | sha1_ctx->lenW = 0; | |
| 752 | } | |
| 753 | ||
| 754 | sha1_ctx->sizeLo += 8; | |
| 755 | sha1_ctx->sizeHi += (sha1_ctx->sizeLo < 8); | |
| 756 | } | |
| 757 | } | |
| 758 | ||
| 759 | static gboolean | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
760 | sha1_digest(GaimCipherContext *context, size_t in_len, guchar digest[20], |
| 10687 | 761 | size_t *out_len) |
| 762 | { | |
| 10684 | 763 | struct SHA1Context *sha1_ctx; |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
764 | guchar pad0x80 = 0x80, pad0x00 = 0x00; |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
765 | guchar padlen[8]; |
| 10684 | 766 | gint i; |
| 767 | ||
| 10687 | 768 | g_return_val_if_fail(in_len >= 20, FALSE); |
| 10684 | 769 | |
| 770 | sha1_ctx = gaim_cipher_context_get_data(context); | |
| 771 | ||
| 772 | g_return_val_if_fail(sha1_ctx, FALSE); | |
| 773 | ||
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
774 | padlen[0] = (guchar)((sha1_ctx->sizeHi >> 24) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
775 | padlen[1] = (guchar)((sha1_ctx->sizeHi >> 16) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
776 | padlen[2] = (guchar)((sha1_ctx->sizeHi >> 8) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
777 | padlen[3] = (guchar)((sha1_ctx->sizeHi >> 0) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
778 | padlen[4] = (guchar)((sha1_ctx->sizeLo >> 24) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
779 | padlen[5] = (guchar)((sha1_ctx->sizeLo >> 16) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
780 | padlen[6] = (guchar)((sha1_ctx->sizeLo >> 8) & 255); |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
781 | padlen[7] = (guchar)((sha1_ctx->sizeLo >> 0) & 255); |
| 10684 | 782 | |
| 783 | /* pad with a 1, then zeroes, then length */ | |
| 784 | gaim_cipher_context_append(context, &pad0x80, 1); | |
| 785 | while(sha1_ctx->lenW != 56) | |
| 786 | gaim_cipher_context_append(context, &pad0x00, 1); | |
| 787 | gaim_cipher_context_append(context, padlen, 8); | |
| 788 | ||
| 789 | for(i = 0; i < 20; i++) { | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
790 | digest[i] = (guchar)(sha1_ctx->H[i / 4] >> 24); |
| 10684 | 791 | sha1_ctx->H[i / 4] <<= 8; |
| 792 | } | |
| 793 | ||
| 794 | gaim_cipher_context_reset(context, NULL); | |
| 795 | ||
| 10687 | 796 | if(out_len) |
| 797 | *out_len = 20; | |
| 798 | ||
| 10684 | 799 | return TRUE; |
| 800 | } | |
| 801 | ||
| 802 | static GaimCipherOps SHA1Ops = { | |
| 803 | sha1_set_opt, /* Set Option */ | |
| 804 | sha1_get_opt, /* Get Option */ | |
| 805 | sha1_init, /* init */ | |
| 806 | sha1_reset, /* reset */ | |
| 807 | sha1_uninit, /* uninit */ | |
| 808 | NULL, /* set iv */ | |
| 809 | sha1_append, /* append */ | |
| 810 | sha1_digest, /* digest */ | |
| 811 | NULL, /* encrypt */ | |
| 812 | NULL, /* decrypt */ | |
| 813 | NULL, /* set salt */ | |
| 814 | NULL, /* get salt size */ | |
| 815 | NULL, /* set key */ | |
| 816 | NULL /* get key size */ | |
| 817 | }; | |
| 818 | ||
| 819 | /******************************************************************************* | |
| 820 | * Structs | |
| 821 | ******************************************************************************/ | |
| 822 | struct _GaimCipher { | |
| 823 | gchar *name; | |
| 824 | GaimCipherOps *ops; | |
| 825 | guint ref; | |
| 826 | }; | |
| 827 | ||
| 828 | struct _GaimCipherContext { | |
| 829 | GaimCipher *cipher; | |
| 830 | gpointer data; | |
| 831 | }; | |
| 832 | ||
| 833 | /****************************************************************************** | |
| 834 | * Globals | |
| 835 | *****************************************************************************/ | |
| 836 | static GList *ciphers = NULL; | |
| 837 | ||
| 838 | /****************************************************************************** | |
| 839 | * GaimCipher API | |
| 840 | *****************************************************************************/ | |
| 841 | const gchar * | |
| 842 | gaim_cipher_get_name(GaimCipher *cipher) { | |
| 843 | g_return_val_if_fail(cipher, NULL); | |
| 844 | ||
| 845 | return cipher->name; | |
| 846 | } | |
| 847 | ||
| 848 | guint | |
| 849 | gaim_cipher_get_capabilities(GaimCipher *cipher) { | |
| 850 | GaimCipherOps *ops = NULL; | |
| 851 | guint caps = 0; | |
| 852 | ||
| 853 | g_return_val_if_fail(cipher, 0); | |
| 854 | ||
| 855 | ops = cipher->ops; | |
| 856 | g_return_val_if_fail(ops, 0); | |
| 857 | ||
| 858 | if(ops->set_option) | |
| 859 | caps |= GAIM_CIPHER_CAPS_SET_OPT; | |
| 860 | if(ops->get_option) | |
| 861 | caps |= GAIM_CIPHER_CAPS_GET_OPT; | |
| 862 | if(ops->init) | |
| 863 | caps |= GAIM_CIPHER_CAPS_INIT; | |
| 864 | if(ops->reset) | |
| 865 | caps |= GAIM_CIPHER_CAPS_RESET; | |
| 866 | if(ops->uninit) | |
| 867 | caps |= GAIM_CIPHER_CAPS_UNINIT; | |
| 868 | if(ops->set_iv) | |
| 869 | caps |= GAIM_CIPHER_CAPS_SET_IV; | |
| 870 | if(ops->append) | |
| 871 | caps |= GAIM_CIPHER_CAPS_APPEND; | |
| 872 | if(ops->digest) | |
| 873 | caps |= GAIM_CIPHER_CAPS_DIGEST; | |
| 874 | if(ops->encrypt) | |
| 875 | caps |= GAIM_CIPHER_CAPS_ENCRYPT; | |
| 876 | if(ops->decrypt) | |
| 877 | caps |= GAIM_CIPHER_CAPS_DECRYPT; | |
| 878 | if(ops->set_salt) | |
| 879 | caps |= GAIM_CIPHER_CAPS_SET_SALT; | |
| 880 | if(ops->get_salt_size) | |
| 881 | caps |= GAIM_CIPHER_CAPS_GET_SALT_SIZE; | |
| 882 | if(ops->set_key) | |
| 883 | caps |= GAIM_CIPHER_CAPS_SET_KEY; | |
| 884 | if(ops->get_key_size) | |
| 885 | caps |= GAIM_CIPHER_CAPS_GET_KEY_SIZE; | |
| 886 | ||
| 887 | return caps; | |
| 888 | } | |
| 889 | ||
| 10687 | 890 | gboolean |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
891 | gaim_cipher_digest_region(const gchar *name, const guchar *data, |
| 10687 | 892 | size_t data_len, size_t in_len, |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
893 | guchar digest[], size_t *out_len) |
| 10684 | 894 | { |
| 895 | GaimCipher *cipher; | |
| 896 | GaimCipherContext *context; | |
| 10687 | 897 | gboolean ret = FALSE; |
| 10684 | 898 | |
| 10687 | 899 | g_return_val_if_fail(name, FALSE); |
| 900 | g_return_val_if_fail(data, FALSE); | |
| 10684 | 901 | |
| 902 | cipher = gaim_ciphers_find_cipher(name); | |
| 903 | ||
| 10687 | 904 | g_return_val_if_fail(cipher, FALSE); |
| 10684 | 905 | |
| 906 | if(!cipher->ops->append || !cipher->ops->digest) { | |
| 907 | gaim_debug_info("cipher", "gaim_cipher_region failed: " | |
| 908 | "the %s cipher does not support appending and or " | |
| 909 | "digesting.", cipher->name); | |
| 10687 | 910 | return FALSE; |
| 10684 | 911 | } |
| 912 | ||
| 913 | context = gaim_cipher_context_new(cipher, NULL); | |
| 914 | gaim_cipher_context_append(context, data, data_len); | |
| 10687 | 915 | ret = gaim_cipher_context_digest(context, in_len, digest, out_len); |
|
11143
f606fb334190
[gaim-migrate @ 13207]
Mark Doliner <markdoliner@pidgin.im>
parents:
10687
diff
changeset
|
916 | gaim_cipher_context_destroy(context); |
| 10687 | 917 | |
| 918 | return ret; | |
| 10684 | 919 | } |
| 920 | ||
| 921 | /****************************************************************************** | |
| 922 | * GaimCiphers API | |
| 923 | *****************************************************************************/ | |
| 924 | GaimCipher * | |
| 925 | gaim_ciphers_find_cipher(const gchar *name) { | |
| 926 | GaimCipher *cipher; | |
| 927 | GList *l; | |
| 928 | ||
| 929 | g_return_val_if_fail(name, NULL); | |
| 930 | ||
| 931 | for(l = ciphers; l; l = l->next) { | |
| 932 | cipher = GAIM_CIPHER(l->data); | |
| 933 | ||
| 934 | if(!g_ascii_strcasecmp(cipher->name, name)) | |
| 935 | return cipher; | |
| 936 | } | |
| 937 | ||
| 938 | return NULL; | |
| 939 | } | |
| 940 | ||
| 941 | GaimCipher * | |
| 942 | gaim_ciphers_register_cipher(const gchar *name, GaimCipherOps *ops) { | |
| 943 | GaimCipher *cipher = NULL; | |
| 944 | ||
| 945 | g_return_val_if_fail(name, NULL); | |
| 946 | g_return_val_if_fail(ops, NULL); | |
| 947 | g_return_val_if_fail(!gaim_ciphers_find_cipher(name), NULL); | |
| 948 | ||
| 949 | cipher = g_new0(GaimCipher, 1); | |
| 950 | ||
| 951 | cipher->name = g_strdup(name); | |
| 952 | cipher->ops = ops; | |
| 953 | ||
| 954 | ciphers = g_list_append(ciphers, cipher); | |
| 955 | ||
| 956 | gaim_signal_emit(gaim_ciphers_get_handle(), "cipher-added", cipher); | |
| 957 | ||
| 958 | return cipher; | |
| 959 | } | |
| 960 | ||
| 961 | gboolean | |
| 962 | gaim_ciphers_unregister_cipher(GaimCipher *cipher) { | |
| 963 | g_return_val_if_fail(cipher, FALSE); | |
| 964 | g_return_val_if_fail(cipher->ref == 0, FALSE); | |
| 965 | ||
| 966 | gaim_signal_emit(gaim_ciphers_get_handle(), "cipher-removed", cipher); | |
| 967 | ||
| 968 | ciphers = g_list_remove(ciphers, cipher); | |
| 969 | ||
| 970 | g_free(cipher->name); | |
| 971 | g_free(cipher); | |
| 972 | ||
| 973 | return TRUE; | |
| 974 | } | |
| 975 | ||
| 976 | GList * | |
| 977 | gaim_ciphers_get_ciphers() { | |
| 978 | return ciphers; | |
| 979 | } | |
| 980 | ||
| 981 | /****************************************************************************** | |
| 982 | * GaimCipher Subsystem API | |
| 983 | *****************************************************************************/ | |
| 984 | gpointer | |
| 985 | gaim_ciphers_get_handle() { | |
| 986 | static gint handle; | |
| 987 | ||
| 988 | return &handle; | |
| 989 | } | |
| 990 | ||
| 991 | void | |
| 992 | gaim_ciphers_init() { | |
| 993 | gpointer handle; | |
| 994 | ||
| 995 | handle = gaim_ciphers_get_handle(); | |
| 996 | ||
| 997 | gaim_signal_register(handle, "cipher-added", | |
| 998 | gaim_marshal_VOID__POINTER, NULL, 1, | |
| 999 | gaim_value_new(GAIM_TYPE_SUBTYPE, | |
| 1000 | GAIM_SUBTYPE_CIPHER)); | |
| 1001 | gaim_signal_register(handle, "cipher-removed", | |
| 1002 | gaim_marshal_VOID__POINTER, NULL, 1, | |
| 1003 | gaim_value_new(GAIM_TYPE_SUBTYPE, | |
| 1004 | GAIM_SUBTYPE_CIPHER)); | |
| 1005 | ||
| 1006 | gaim_ciphers_register_cipher("md5", &MD5Ops); | |
| 1007 | gaim_ciphers_register_cipher("sha1", &SHA1Ops); | |
|
11329
5ca3cf4e502e
[gaim-migrate @ 13541]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11183
diff
changeset
|
1008 | gaim_ciphers_register_cipher("md4", &MD4Ops); |
| 10684 | 1009 | } |
| 1010 | ||
| 1011 | void | |
| 1012 | gaim_ciphers_uninit() { | |
| 1013 | GaimCipher *cipher; | |
| 1014 | GList *l, *ll; | |
| 1015 | ||
| 1016 | for(l = ciphers; l; l = ll) { | |
| 1017 | ll = l->next; | |
| 1018 | ||
| 1019 | cipher = GAIM_CIPHER(l->data); | |
| 1020 | gaim_ciphers_unregister_cipher(cipher); | |
| 1021 | ||
| 1022 | ciphers = g_list_remove(ciphers, cipher); | |
| 1023 | } | |
| 1024 | ||
| 1025 | g_list_free(ciphers); | |
| 1026 | ||
| 1027 | gaim_signals_unregister_by_instance(gaim_ciphers_get_handle()); | |
| 1028 | } | |
| 1029 | /****************************************************************************** | |
| 1030 | * GaimCipherContext API | |
| 1031 | *****************************************************************************/ | |
| 1032 | void | |
| 1033 | gaim_cipher_context_set_option(GaimCipherContext *context, const gchar *name, | |
| 1034 | gpointer value) | |
| 1035 | { | |
| 1036 | GaimCipher *cipher = NULL; | |
| 1037 | ||
| 1038 | g_return_if_fail(context); | |
| 1039 | g_return_if_fail(name); | |
| 1040 | ||
| 1041 | cipher = context->cipher; | |
| 1042 | g_return_if_fail(cipher); | |
| 1043 | ||
| 1044 | if(cipher->ops && cipher->ops->set_option) | |
| 1045 | cipher->ops->set_option(context, name, value); | |
| 1046 | else | |
| 1047 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1048 | "set_option operation\n", cipher->name); | |
| 1049 | } | |
| 1050 | ||
| 1051 | gpointer | |
| 1052 | gaim_cipher_context_get_option(GaimCipherContext *context, const gchar *name) { | |
| 1053 | GaimCipher *cipher = NULL; | |
| 1054 | ||
| 1055 | g_return_val_if_fail(context, NULL); | |
| 1056 | g_return_val_if_fail(name, NULL); | |
| 1057 | ||
| 1058 | cipher = context->cipher; | |
| 1059 | g_return_val_if_fail(cipher, NULL); | |
| 1060 | ||
| 1061 | if(cipher->ops && cipher->ops->get_option) | |
| 1062 | return cipher->ops->get_option(context, name); | |
| 1063 | else { | |
| 1064 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1065 | "get_option operation\n", cipher->name); | |
| 1066 | ||
| 1067 | return NULL; | |
| 1068 | } | |
| 1069 | } | |
| 1070 | ||
| 1071 | GaimCipherContext * | |
| 1072 | gaim_cipher_context_new(GaimCipher *cipher, void *extra) { | |
| 1073 | GaimCipherContext *context = NULL; | |
| 1074 | ||
| 1075 | g_return_val_if_fail(cipher, NULL); | |
| 1076 | ||
| 1077 | cipher->ref++; | |
| 1078 | ||
| 1079 | context = g_new0(GaimCipherContext, 1); | |
| 1080 | context->cipher = cipher; | |
| 1081 | ||
| 1082 | if(cipher->ops->init) | |
| 1083 | cipher->ops->init(context, extra); | |
| 1084 | ||
| 1085 | return context; | |
| 1086 | } | |
| 1087 | ||
| 1088 | GaimCipherContext * | |
| 1089 | gaim_cipher_context_new_by_name(const gchar *name, void *extra) { | |
| 1090 | GaimCipher *cipher; | |
| 1091 | ||
| 1092 | g_return_val_if_fail(name, NULL); | |
| 1093 | ||
| 1094 | cipher = gaim_ciphers_find_cipher(name); | |
| 1095 | ||
| 1096 | g_return_val_if_fail(cipher, NULL); | |
| 1097 | ||
| 1098 | return gaim_cipher_context_new(cipher, extra); | |
| 1099 | } | |
| 1100 | ||
| 1101 | void | |
| 1102 | gaim_cipher_context_reset(GaimCipherContext *context, void *extra) { | |
| 1103 | GaimCipher *cipher = NULL; | |
| 1104 | ||
| 1105 | g_return_if_fail(context); | |
| 1106 | ||
| 1107 | cipher = context->cipher; | |
| 1108 | g_return_if_fail(cipher); | |
| 1109 | ||
| 1110 | if(cipher->ops && cipher->ops->reset) | |
| 1111 | context->cipher->ops->reset(context, extra); | |
| 1112 | } | |
| 1113 | ||
| 1114 | void | |
| 1115 | gaim_cipher_context_destroy(GaimCipherContext *context) { | |
| 1116 | GaimCipher *cipher = NULL; | |
| 1117 | ||
| 1118 | g_return_if_fail(context); | |
| 1119 | ||
| 1120 | cipher = context->cipher; | |
| 1121 | g_return_if_fail(cipher); | |
| 1122 | ||
| 1123 | cipher->ref--; | |
| 1124 | ||
| 1125 | if(cipher->ops && cipher->ops->uninit) | |
| 1126 | cipher->ops->uninit(context); | |
| 1127 | ||
| 1128 | memset(context, 0, sizeof(context)); | |
| 1129 | g_free(context); | |
| 1130 | context = NULL; | |
| 1131 | } | |
| 1132 | ||
| 1133 | void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1134 | gaim_cipher_context_set_iv(GaimCipherContext *context, guchar *iv, size_t len) |
| 10684 | 1135 | { |
| 1136 | GaimCipher *cipher = NULL; | |
| 1137 | ||
| 1138 | g_return_if_fail(context); | |
| 1139 | g_return_if_fail(iv); | |
| 1140 | ||
| 1141 | cipher = context->cipher; | |
| 1142 | g_return_if_fail(cipher); | |
| 1143 | ||
| 1144 | if(cipher->ops && cipher->ops->set_iv) | |
| 1145 | cipher->ops->set_iv(context, iv, len); | |
| 1146 | else | |
| 1147 | gaim_debug_info("cipher", "the %s cipher does not support the set" | |
| 1148 | "initialization vector operation\n", cipher->name); | |
| 1149 | } | |
| 1150 | ||
| 1151 | void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1152 | gaim_cipher_context_append(GaimCipherContext *context, const guchar *data, |
| 10684 | 1153 | size_t len) |
| 1154 | { | |
| 1155 | GaimCipher *cipher = NULL; | |
| 1156 | ||
| 1157 | g_return_if_fail(context); | |
| 1158 | ||
| 1159 | cipher = context->cipher; | |
| 1160 | g_return_if_fail(cipher); | |
| 1161 | ||
| 1162 | if(cipher->ops && cipher->ops->append) | |
| 1163 | cipher->ops->append(context, data, len); | |
| 1164 | else | |
| 1165 | gaim_debug_info("cipher", "the %s cipher does not support the append " | |
| 1166 | "operation\n", cipher->name); | |
| 1167 | } | |
| 1168 | ||
| 1169 | gboolean | |
| 10687 | 1170 | gaim_cipher_context_digest(GaimCipherContext *context, size_t in_len, |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1171 | guchar digest[], size_t *out_len) |
| 10684 | 1172 | { |
| 1173 | GaimCipher *cipher = NULL; | |
| 1174 | ||
| 1175 | g_return_val_if_fail(context, FALSE); | |
| 1176 | ||
| 1177 | cipher = context->cipher; | |
| 1178 | g_return_val_if_fail(context, FALSE); | |
| 1179 | ||
| 1180 | if(cipher->ops && cipher->ops->digest) | |
| 10687 | 1181 | return cipher->ops->digest(context, in_len, digest, out_len); |
| 10684 | 1182 | else { |
| 1183 | gaim_debug_info("cipher", "the %s cipher does not support the digest " | |
| 1184 | "operation\n", cipher->name); | |
| 1185 | return FALSE; | |
| 1186 | } | |
| 1187 | } | |
| 1188 | ||
| 1189 | gboolean | |
| 10687 | 1190 | gaim_cipher_context_digest_to_str(GaimCipherContext *context, size_t in_len, |
| 1191 | gchar digest_s[], size_t *out_len) | |
| 10684 | 1192 | { |
| 10687 | 1193 | /* 8k is a bit excessive, will tweak later. */ |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1194 | guchar digest[BUF_LEN * 4]; |
| 10684 | 1195 | gint n = 0; |
| 1196 | size_t dlen = 0; | |
| 1197 | ||
| 1198 | g_return_val_if_fail(context, FALSE); | |
| 1199 | g_return_val_if_fail(digest_s, FALSE); | |
| 1200 | ||
| 10687 | 1201 | if(!gaim_cipher_context_digest(context, sizeof(digest), digest, &dlen)) |
| 10684 | 1202 | return FALSE; |
| 1203 | ||
| 10687 | 1204 | if(in_len < dlen * 2) |
| 1205 | return FALSE; | |
| 10684 | 1206 | |
| 1207 | for(n = 0; n < dlen; n++) | |
| 1208 | sprintf(digest_s + (n * 2), "%02x", digest[n]); | |
| 1209 | ||
| 1210 | digest_s[n * 2] = '\0'; | |
| 1211 | ||
| 10687 | 1212 | if(out_len) |
| 1213 | *out_len = dlen * 2; | |
| 1214 | ||
| 10684 | 1215 | return TRUE; |
| 1216 | } | |
| 1217 | ||
| 1218 | gint | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1219 | gaim_cipher_context_encrypt(GaimCipherContext *context, const guchar data[], |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1220 | size_t len, guchar output[], size_t *outlen) |
| 10684 | 1221 | { |
| 1222 | GaimCipher *cipher = NULL; | |
| 1223 | ||
| 1224 | g_return_val_if_fail(context, -1); | |
| 1225 | ||
| 1226 | cipher = context->cipher; | |
| 1227 | g_return_val_if_fail(cipher, -1); | |
| 1228 | ||
| 1229 | if(cipher->ops && cipher->ops->encrypt) | |
| 1230 | return cipher->ops->encrypt(context, data, len, output, outlen); | |
| 1231 | else { | |
| 1232 | gaim_debug_info("cipher", "the %s cipher does not support the encrypt" | |
| 1233 | "operation\n", cipher->name); | |
| 1234 | ||
| 1235 | if(outlen) | |
| 1236 | *outlen = -1; | |
| 1237 | ||
| 1238 | return -1; | |
| 1239 | } | |
| 1240 | } | |
| 1241 | ||
| 1242 | gint | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1243 | gaim_cipher_context_decrypt(GaimCipherContext *context, const guchar data[], |
|
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1244 | size_t len, guchar output[], size_t *outlen) |
| 10684 | 1245 | { |
| 1246 | GaimCipher *cipher = NULL; | |
| 1247 | ||
| 1248 | g_return_val_if_fail(context, -1); | |
| 1249 | ||
| 1250 | cipher = context->cipher; | |
| 1251 | g_return_val_if_fail(cipher, -1); | |
| 1252 | ||
| 1253 | if(cipher->ops && cipher->ops->decrypt) | |
| 1254 | return cipher->ops->decrypt(context, data, len, output, outlen); | |
| 1255 | else { | |
| 1256 | gaim_debug_info("cipher", "the %s cipher does not support the decrypt" | |
| 1257 | "operation\n", cipher->name); | |
| 1258 | ||
| 1259 | if(outlen) | |
| 1260 | *outlen = -1; | |
| 1261 | ||
| 1262 | return -1; | |
| 1263 | } | |
| 1264 | } | |
| 1265 | ||
| 1266 | void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1267 | gaim_cipher_context_set_salt(GaimCipherContext *context, guchar *salt) { |
| 10684 | 1268 | GaimCipher *cipher = NULL; |
| 1269 | ||
| 1270 | g_return_if_fail(context); | |
| 1271 | ||
| 1272 | cipher = context->cipher; | |
| 1273 | g_return_if_fail(cipher); | |
| 1274 | ||
| 1275 | if(cipher->ops && cipher->ops->set_salt) | |
| 1276 | cipher->ops->set_salt(context, salt); | |
| 1277 | else | |
| 1278 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1279 | "set_salt operation\n", cipher->name); | |
| 1280 | } | |
| 1281 | ||
| 1282 | size_t | |
| 1283 | gaim_cipher_context_get_salt_size(GaimCipherContext *context) { | |
| 1284 | GaimCipher *cipher = NULL; | |
| 1285 | ||
| 1286 | g_return_val_if_fail(context, -1); | |
| 1287 | ||
| 1288 | cipher = context->cipher; | |
| 1289 | g_return_val_if_fail(cipher, -1); | |
| 1290 | ||
| 1291 | if(cipher->ops && cipher->ops->get_salt_size) | |
| 1292 | return cipher->ops->get_salt_size(context); | |
| 1293 | else { | |
| 1294 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1295 | "get_salt_size operation\n", cipher->name); | |
| 1296 | ||
| 1297 | return -1; | |
| 1298 | } | |
| 1299 | } | |
| 1300 | ||
| 1301 | void | |
|
11183
be87fe695c93
[gaim-migrate @ 13295]
Mark Doliner <markdoliner@pidgin.im>
parents:
11143
diff
changeset
|
1302 | gaim_cipher_context_set_key(GaimCipherContext *context, guchar *key) { |
| 10684 | 1303 | GaimCipher *cipher = NULL; |
| 1304 | ||
| 1305 | g_return_if_fail(context); | |
| 1306 | ||
| 1307 | cipher = context->cipher; | |
| 1308 | g_return_if_fail(cipher); | |
| 1309 | ||
| 1310 | if(cipher->ops && cipher->ops->set_key) | |
| 1311 | cipher->ops->set_key(context, key); | |
| 1312 | else | |
| 1313 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1314 | "set_key operation\n", cipher->name); | |
| 1315 | } | |
| 1316 | ||
| 1317 | size_t | |
| 1318 | gaim_cipher_context_get_key_size(GaimCipherContext *context) { | |
| 1319 | GaimCipher *cipher = NULL; | |
| 1320 | ||
| 1321 | g_return_val_if_fail(context, -1); | |
| 1322 | ||
| 1323 | cipher = context->cipher; | |
| 1324 | g_return_val_if_fail(cipher, -1); | |
| 1325 | ||
| 1326 | if(cipher->ops && cipher->ops->get_key_size) | |
| 1327 | return cipher->ops->get_key_size(context); | |
| 1328 | else { | |
| 1329 | gaim_debug_info("cipher", "the %s cipher does not support the " | |
| 1330 | "get_key_size operation\n", cipher->name); | |
| 1331 | ||
| 1332 | return -1; | |
| 1333 | } | |
| 1334 | } | |
| 1335 | ||
| 1336 | void | |
| 1337 | gaim_cipher_context_set_data(GaimCipherContext *context, gpointer data) { | |
| 1338 | g_return_if_fail(context); | |
| 1339 | ||
| 1340 | context->data = data; | |
| 1341 | } | |
| 1342 | ||
| 1343 | gpointer | |
| 1344 | gaim_cipher_context_get_data(GaimCipherContext *context) { | |
| 1345 | g_return_val_if_fail(context, NULL); | |
| 1346 | ||
| 1347 | return context->data; | |
| 1348 | } |