Mercurial > pidgin
comparison src/protocols/sametime/meanwhile/cipher.c @ 10969:3ef77720e577
[gaim-migrate @ 12790]
importing meanwhile library for use in the sametime plugin
committer: Tailor Script <tailor@pidgin.im>
author | Christopher O'Brien <siege@pidgin.im> |
---|---|
date | Sun, 05 Jun 2005 02:50:13 +0000 |
parents | |
children | 0110fc7c6a8a |
comparison
equal
deleted
inserted
replaced
10968:e0d5038fbb7e | 10969:3ef77720e577 |
---|---|
1 | |
2 /* | |
3 Meanwhile - Unofficial Lotus Sametime Community Client Library | |
4 Copyright (C) 2004 Christopher (siege) O'Brien | |
5 | |
6 This library is free software; you can redistribute it and/or | |
7 modify it under the terms of the GNU Library General Public | |
8 License as published by the Free Software Foundation; either | |
9 version 2 of the License, or (at your option) any later version. | |
10 | |
11 This library is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 Library General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU Library General Public | |
17 License along with this library; if not, write to the Free | |
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 */ | |
20 | |
21 #include <stdlib.h> | |
22 #include <string.h> | |
23 #include <time.h> | |
24 | |
25 #include "mw_channel.h" | |
26 #include "mw_cipher.h" | |
27 #include "mw_debug.h" | |
28 #include "mw_session.h" | |
29 | |
30 | |
31 /** From RFC2268 */ | |
32 static unsigned char PT[] = { | |
33 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, | |
34 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, | |
35 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, | |
36 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, | |
37 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, | |
38 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, | |
39 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, | |
40 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, | |
41 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, | |
42 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, | |
43 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, | |
44 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, | |
45 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, | |
46 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, | |
47 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, | |
48 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, | |
49 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, | |
50 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, | |
51 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, | |
52 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, | |
53 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, | |
54 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, | |
55 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, | |
56 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, | |
57 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, | |
58 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, | |
59 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, | |
60 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, | |
61 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, | |
62 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, | |
63 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, | |
64 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD | |
65 }; | |
66 | |
67 | |
68 void rand_key(char *key, gsize keylen) { | |
69 srand(clock()); | |
70 while(keylen--) key[keylen] = rand() & 0xff; | |
71 } | |
72 | |
73 | |
74 void mwIV_init(char *iv) { | |
75 static unsigned char normal_iv[] = { | |
76 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef | |
77 }; | |
78 memcpy(iv, normal_iv, 8); | |
79 | |
80 /* | |
81 *iv++ = 0x01; *iv++ = 0x23; | |
82 *iv++ = 0x45; *iv++ = 0x67; | |
83 *iv++ = 0x89; *iv++ = 0xab; | |
84 *iv++ = 0xcd; *iv = 0xef; | |
85 */ | |
86 } | |
87 | |
88 | |
89 /* This does not seem to produce the same results as normal RC2 key | |
90 expansion would, but it works, so eh. It might be smart to farm | |
91 this out to mozilla or openssl */ | |
92 void mwKeyExpand(int *ekey, const char *key, gsize keylen) { | |
93 char tmp[128]; | |
94 int i, j; | |
95 | |
96 /* | |
97 g_message("expanding key from:"); | |
98 pretty_print(key, keylen); | |
99 */ | |
100 | |
101 if(keylen > 128) keylen = 128; | |
102 memcpy(tmp, key, keylen); | |
103 | |
104 for(i = 0; keylen < 128; i++) { | |
105 tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ]; | |
106 keylen++; | |
107 } | |
108 | |
109 tmp[0] = PT[ tmp[0] & 0xff ]; | |
110 | |
111 for(i = 0, j = 0; i < 64; i++) { | |
112 ekey[i] = (tmp[j] & 0xff) | (tmp[j+1] << 8); | |
113 j += 2; | |
114 } | |
115 } | |
116 | |
117 | |
118 /* normal RC2 encryption given a full 128-byte (as 64 ints) key */ | |
119 static void mwEncryptBlock(const int *ekey, char *out) { | |
120 int a = (out[7] << 8) | (out[6] & 0xff); | |
121 int b = (out[5] << 8) | (out[4] & 0xff); | |
122 int c = (out[3] << 8) | (out[2] & 0xff); | |
123 int d = (out[1] << 8) | (out[0] & 0xff); | |
124 | |
125 int i, j; | |
126 | |
127 for(i = 0; i < 16; i++) { | |
128 j = i * 4; | |
129 | |
130 d += ((c & (a ^ 0xffff)) + (b & a) + ekey[j++]); | |
131 d = (d << 1) | (d >> 15 & 0x0001); | |
132 | |
133 c += ((b & (d ^ 0xffff)) + (a & d) + ekey[j++]); | |
134 c = (c << 2) | (c >> 14 & 0x0003); | |
135 | |
136 b += ((a & (c ^ 0xffff)) + (d & c) + ekey[j++]); | |
137 b = (b << 3) | (b >> 13 & 0x0007); | |
138 | |
139 a += ((d & (b ^ 0xffff)) + (c & b) + ekey[j++]); | |
140 a = (a << 5) | (a >> 11 & 0x001f); | |
141 | |
142 if(i == 4 || i == 10) { | |
143 d += ekey[a & 0x003f]; | |
144 c += ekey[d & 0x003f]; | |
145 b += ekey[c & 0x003f]; | |
146 a += ekey[b & 0x003f]; | |
147 } | |
148 } | |
149 | |
150 *out++ = d & 0xff; | |
151 *out++ = (d >> 8) & 0xff; | |
152 *out++ = c & 0xff; | |
153 *out++ = (c >> 8) & 0xff; | |
154 *out++ = b & 0xff; | |
155 *out++ = (b >> 8) & 0xff; | |
156 *out++ = a & 0xff; | |
157 *out++ = (a >> 8) & 0xff; | |
158 } | |
159 | |
160 | |
161 void mwEncryptExpanded(const int *ekey, char *iv, | |
162 struct mwOpaque *in_data, | |
163 struct mwOpaque *out_data) { | |
164 | |
165 char *i = in_data->data; | |
166 gsize i_len = in_data->len; | |
167 | |
168 char *o; | |
169 gsize o_len; | |
170 | |
171 int x, y; | |
172 | |
173 /* pad upwards to a multiple of 8 */ | |
174 o_len = (i_len & -8) + 8; | |
175 o = g_malloc(o_len); | |
176 | |
177 out_data->data = o; | |
178 out_data->len = o_len; | |
179 | |
180 /* figure out the amount of padding */ | |
181 y = o_len - i_len; | |
182 | |
183 /* copy in to out, and write padding bytes */ | |
184 memcpy(o, i, i_len); | |
185 memset(o + i_len, y, y); | |
186 | |
187 /* encrypt in blocks */ | |
188 for(x = o_len; x > 0; x -= 8) { | |
189 for(y = 8; y--; o[y] ^= iv[y]); | |
190 mwEncryptBlock(ekey, o); | |
191 memcpy(iv, o, 8); | |
192 o += 8; | |
193 } | |
194 } | |
195 | |
196 | |
197 void mwEncrypt(const char *key, gsize keylen, char *iv, | |
198 struct mwOpaque *in, struct mwOpaque *out) { | |
199 | |
200 int ekey[64]; | |
201 mwKeyExpand(ekey, key, keylen); | |
202 mwEncryptExpanded(ekey, iv, in, out); | |
203 } | |
204 | |
205 | |
206 static void mwDecryptBlock(const int *ekey, char *out) { | |
207 int a = (out[7] << 8) | (out[6] & 0xff); | |
208 int b = (out[5] << 8) | (out[4] & 0xff); | |
209 int c = (out[3] << 8) | (out[2] & 0xff); | |
210 int d = (out[1] << 8) | (out[0] & 0xff); | |
211 | |
212 int i, j; | |
213 | |
214 for(i = 16; i--; ) { | |
215 j = i * 4 + 3; | |
216 | |
217 a = (a << 11) | (a >> 5 & 0x07ff); | |
218 a -= ((d & (b ^ 0xffff)) + (c & b) + ekey[j--]); | |
219 | |
220 b = (b << 13) | (b >> 3 & 0x1fff); | |
221 b -= ((a & (c ^ 0xffff)) + (d & c) + ekey[j--]); | |
222 | |
223 c = (c << 14) | (c >> 2 & 0x3fff); | |
224 c -= ((b & (d ^ 0xffff)) + (a & d) + ekey[j--]); | |
225 | |
226 d = (d << 15) | (d >> 1 & 0x7fff); | |
227 d -= ((c & (a ^ 0xffff)) + (b & a) + ekey[j--]); | |
228 | |
229 if(i == 5 || i == 11) { | |
230 a -= ekey[b & 0x003f]; | |
231 b -= ekey[c & 0x003f]; | |
232 c -= ekey[d & 0x003f]; | |
233 d -= ekey[a & 0x003f]; | |
234 } | |
235 } | |
236 | |
237 *out++ = d & 0xff; | |
238 *out++ = (d >> 8) & 0xff; | |
239 *out++ = c & 0xff; | |
240 *out++ = (c >> 8) & 0xff; | |
241 *out++ = b & 0xff; | |
242 *out++ = (b >> 8) & 0xff; | |
243 *out++ = a & 0xff; | |
244 *out++ = (a >> 8) & 0xff; | |
245 } | |
246 | |
247 | |
248 void mwDecryptExpanded(const int *ekey, char *iv, | |
249 struct mwOpaque *in_data, | |
250 struct mwOpaque *out_data) { | |
251 | |
252 char *i = in_data->data; | |
253 gsize i_len = in_data->len; | |
254 | |
255 char *o; | |
256 gsize o_len; | |
257 | |
258 int x, y; | |
259 | |
260 /* this doesn't check to ensure that in_data->len is a multiple of | |
261 8, which is damn well ought to be. */ | |
262 | |
263 o = g_malloc(i_len); | |
264 o_len = i_len; | |
265 memcpy(o, i, i_len); | |
266 | |
267 out_data->data = o; | |
268 out_data->len = o_len; | |
269 | |
270 for(x = o_len; x > 0; x -= 8) { | |
271 /* decrypt a block */ | |
272 mwDecryptBlock(ekey, o); | |
273 | |
274 /* modify the initialization vector */ | |
275 for(y = 8; y--; o[y] ^= iv[y]); | |
276 memcpy(iv, i, 8); | |
277 i += 8; | |
278 o += 8; | |
279 } | |
280 | |
281 /* shorten the length by the value of the filler in the padding | |
282 bytes */ | |
283 out_data->len -= *(o - 1); | |
284 } | |
285 | |
286 | |
287 void mwDecrypt(const char *key, gsize keylen, char *iv, | |
288 struct mwOpaque *in, struct mwOpaque *out) { | |
289 | |
290 int ekey[64]; | |
291 mwKeyExpand(ekey, key, keylen); | |
292 mwDecryptExpanded(ekey, iv, in, out); | |
293 } | |
294 | |
295 | |
296 struct mwCipher_RC2_40 { | |
297 struct mwCipher cipher; | |
298 int session_key[64]; | |
299 gboolean ready; | |
300 }; | |
301 | |
302 | |
303 struct mwCipherInstance_RC2_40 { | |
304 struct mwCipherInstance instance; | |
305 int incoming_key[64]; | |
306 char outgoing_iv[8]; | |
307 char incoming_iv[8]; | |
308 }; | |
309 | |
310 | |
311 static const char *get_name_RC2_40() { | |
312 return "RC2/40 Cipher"; | |
313 } | |
314 | |
315 | |
316 static const char *get_desc_RC2_40() { | |
317 return "RC2, 40-bit effective key"; | |
318 } | |
319 | |
320 | |
321 static int encrypt_RC2_40(struct mwCipherInstance *ci, | |
322 struct mwOpaque *data) { | |
323 | |
324 struct mwCipherInstance_RC2_40 *cir; | |
325 struct mwCipher_RC2_40 *cr; | |
326 struct mwOpaque o = { 0, 0 }; | |
327 | |
328 cir = (struct mwCipherInstance_RC2_40 *) ci; | |
329 cr = (struct mwCipher_RC2_40 *) ci->cipher; | |
330 | |
331 mwEncryptExpanded(cr->session_key, cir->outgoing_iv, data, &o); | |
332 | |
333 mwOpaque_clear(data); | |
334 data->data = o.data; | |
335 data->len = o.len; | |
336 | |
337 return 0; | |
338 } | |
339 | |
340 | |
341 static int decrypt_RC2_40(struct mwCipherInstance *ci, | |
342 struct mwOpaque *data) { | |
343 | |
344 struct mwCipherInstance_RC2_40 *cir; | |
345 struct mwCipher_RC2_40 *cr; | |
346 struct mwOpaque o = { 0, 0 }; | |
347 | |
348 cir = (struct mwCipherInstance_RC2_40 *) ci; | |
349 cr = (struct mwCipher_RC2_40 *) ci->cipher; | |
350 | |
351 mwDecryptExpanded(cir->incoming_key, cir->incoming_iv, data, &o); | |
352 | |
353 mwOpaque_clear(data); | |
354 data->data = o.data; | |
355 data->len = o.len; | |
356 | |
357 return 0; | |
358 } | |
359 | |
360 | |
361 static struct mwCipherInstance *new_instance_RC2_40(struct mwCipher *cipher, | |
362 struct mwChannel *chan) { | |
363 struct mwCipher_RC2_40 *cr; | |
364 struct mwCipherInstance_RC2_40 *cir; | |
365 struct mwCipherInstance *ci; | |
366 | |
367 cr = (struct mwCipher_RC2_40 *) cipher; | |
368 | |
369 cir = g_new0(struct mwCipherInstance_RC2_40, 1); | |
370 ci = &cir->instance; | |
371 | |
372 ci->cipher = cipher; | |
373 ci->channel = chan; | |
374 | |
375 /* a bit of lazy initialization here */ | |
376 if(! cr->ready) { | |
377 struct mwLoginInfo *info = mwSession_getLoginInfo(cipher->session); | |
378 mwKeyExpand(cr->session_key, info->login_id, 5); | |
379 cr->ready = TRUE; | |
380 } | |
381 | |
382 mwIV_init(cir->incoming_iv); | |
383 mwIV_init(cir->outgoing_iv); | |
384 | |
385 return ci; | |
386 } | |
387 | |
388 | |
389 static struct mwEncryptItem *new_item_RC2_40(struct mwCipherInstance *ci) { | |
390 struct mwEncryptItem *e = g_new0(struct mwEncryptItem, 1); | |
391 e->id = mwCipher_RC2_40; | |
392 return e; | |
393 } | |
394 | |
395 | |
396 static void accept_RC2_40(struct mwCipherInstance *ci) { | |
397 struct mwCipherInstance_RC2_40 *cir; | |
398 struct mwLoginInfo *info = mwChannel_getUser(ci->channel); | |
399 | |
400 cir = (struct mwCipherInstance_RC2_40 *) ci; | |
401 mwKeyExpand(cir->incoming_key, info->login_id, 5); | |
402 } | |
403 | |
404 | |
405 static void accepted_RC2_40(struct mwCipherInstance *ci, | |
406 struct mwEncryptItem *item) { | |
407 accept_RC2_40(ci); | |
408 } | |
409 | |
410 | |
411 struct mwCipher *mwCipher_new_RC2_40(struct mwSession *s) { | |
412 struct mwCipher_RC2_40 *cr = g_new0(struct mwCipher_RC2_40, 1); | |
413 struct mwCipher *c = &cr->cipher; | |
414 | |
415 c->session = s; | |
416 c->type = mwCipher_RC2_40; | |
417 c->get_name = get_name_RC2_40; | |
418 c->get_desc = get_desc_RC2_40; | |
419 c->new_instance = new_instance_RC2_40; | |
420 c->new_item = new_item_RC2_40; | |
421 | |
422 c->accepted = accepted_RC2_40; | |
423 c->accept = accept_RC2_40; | |
424 | |
425 c->encrypt = encrypt_RC2_40; | |
426 c->decrypt = decrypt_RC2_40; | |
427 | |
428 return c; | |
429 } | |
430 | |
431 | |
432 struct mwSession *mwCipher_getSession(struct mwCipher *cipher) { | |
433 g_return_val_if_fail(cipher != NULL, NULL); | |
434 return cipher->session; | |
435 } | |
436 | |
437 | |
438 guint16 mwCipher_getType(struct mwCipher *cipher) { | |
439 /* oh man, this is a bad failover... who the hell decided to make | |
440 zero a real cipher id?? */ | |
441 g_return_val_if_fail(cipher != NULL, 0x00); | |
442 return cipher->type; | |
443 } | |
444 | |
445 | |
446 const char *mwCipher_getName(struct mwCipher *cipher) { | |
447 g_return_val_if_fail(cipher != NULL, NULL); | |
448 g_return_val_if_fail(cipher->get_name != NULL, NULL); | |
449 return cipher->get_name(); | |
450 } | |
451 | |
452 | |
453 const char *mwCipher_getDesc(struct mwCipher *cipher) { | |
454 g_return_val_if_fail(cipher != NULL, NULL); | |
455 g_return_val_if_fail(cipher->get_desc != NULL, NULL); | |
456 return cipher->get_desc(); | |
457 } | |
458 | |
459 | |
460 void mwCipher_free(struct mwCipher *cipher) { | |
461 if(! cipher) return; | |
462 | |
463 if(cipher->clear) | |
464 cipher->clear(cipher); | |
465 | |
466 g_free(cipher); | |
467 } | |
468 | |
469 | |
470 struct mwCipherInstance *mwCipher_newInstance(struct mwCipher *cipher, | |
471 struct mwChannel *chan) { | |
472 g_return_val_if_fail(cipher != NULL, NULL); | |
473 g_return_val_if_fail(chan != NULL, NULL); | |
474 g_return_val_if_fail(cipher->new_instance != NULL, NULL); | |
475 return cipher->new_instance(cipher, chan); | |
476 } | |
477 | |
478 | |
479 struct mwCipher *mwCipherInstance_getCipher(struct mwCipherInstance *ci) { | |
480 g_return_val_if_fail(ci != NULL, NULL); | |
481 return ci->cipher; | |
482 } | |
483 | |
484 | |
485 struct mwChannel *mwCipherInstance_getChannel(struct mwCipherInstance *ci) { | |
486 g_return_val_if_fail(ci != NULL, NULL); | |
487 return ci->channel; | |
488 } | |
489 | |
490 | |
491 struct mwEncryptItem *mwCipherInstance_newItem(struct mwCipherInstance *ci) { | |
492 struct mwCipher *cipher; | |
493 | |
494 g_return_val_if_fail(ci != NULL, NULL); | |
495 cipher = ci->cipher; | |
496 | |
497 g_return_val_if_fail(cipher != NULL, NULL); | |
498 g_return_val_if_fail(cipher->new_item != NULL, NULL); | |
499 | |
500 return cipher->new_item(ci); | |
501 } | |
502 | |
503 | |
504 void mwCipherInstance_offered(struct mwCipherInstance *ci, | |
505 struct mwEncryptItem *item) { | |
506 struct mwCipher *cipher; | |
507 | |
508 g_return_if_fail(ci != NULL); | |
509 | |
510 cipher = ci->cipher; | |
511 g_return_if_fail(cipher != NULL); | |
512 | |
513 if(cipher->offered) cipher->offered(ci, item); | |
514 } | |
515 | |
516 | |
517 void mwCipherInstance_offer(struct mwCipherInstance *ci) { | |
518 struct mwCipher *cipher; | |
519 | |
520 g_return_if_fail(ci != NULL); | |
521 | |
522 cipher = ci->cipher; | |
523 g_return_if_fail(cipher != NULL); | |
524 | |
525 if(cipher->offer) cipher->offer(ci); | |
526 } | |
527 | |
528 | |
529 void mwCipherInstance_accepted(struct mwCipherInstance *ci, | |
530 struct mwEncryptItem *item) { | |
531 struct mwCipher *cipher; | |
532 | |
533 g_return_if_fail(ci != NULL); | |
534 | |
535 cipher = ci->cipher; | |
536 g_return_if_fail(cipher != NULL); | |
537 | |
538 if(cipher->accepted) cipher->accepted(ci, item); | |
539 } | |
540 | |
541 | |
542 void mwCipherInstance_accept(struct mwCipherInstance *ci) { | |
543 struct mwCipher *cipher; | |
544 | |
545 g_return_if_fail(ci != NULL); | |
546 | |
547 cipher = ci->cipher; | |
548 g_return_if_fail(cipher != NULL); | |
549 | |
550 if(cipher->accept) cipher->accept(ci); | |
551 } | |
552 | |
553 | |
554 int mwCipherInstance_encrypt(struct mwCipherInstance *ci, | |
555 struct mwOpaque *data) { | |
556 struct mwCipher *cipher; | |
557 | |
558 g_return_val_if_fail(data != NULL, 0); | |
559 | |
560 if(! ci) return 0; | |
561 cipher = ci->cipher; | |
562 | |
563 g_return_val_if_fail(cipher != NULL, -1); | |
564 | |
565 return (cipher->encrypt)? | |
566 cipher->encrypt(ci, data): 0; | |
567 } | |
568 | |
569 | |
570 int mwCipherInstance_decrypt(struct mwCipherInstance *ci, | |
571 struct mwOpaque *data) { | |
572 struct mwCipher *cipher; | |
573 | |
574 g_return_val_if_fail(data != NULL, 0); | |
575 | |
576 if(! ci) return 0; | |
577 cipher = ci->cipher; | |
578 | |
579 g_return_val_if_fail(cipher != NULL, -1); | |
580 | |
581 return (cipher->decrypt)? | |
582 cipher->decrypt(ci, data): 0; | |
583 } | |
584 | |
585 | |
586 void mwCipherInstance_free(struct mwCipherInstance *ci) { | |
587 struct mwCipher *cipher; | |
588 | |
589 if(! ci) return; | |
590 | |
591 cipher = ci->cipher; | |
592 | |
593 if(cipher && cipher->clear_instance) | |
594 cipher->clear_instance(ci); | |
595 | |
596 g_free(ci); | |
597 } | |
598 |