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 <time.h>
23
24 #include "mpi/mpi.h"
25
26 #include "mw_channel.h"
27 #include "mw_cipher.h"
28 #include "mw_debug.h"
29 #include "mw_session.h"
30
31
32 struct mwMpi {
33 mw_mp_int i;
34 };
35
36
37 /** From RFC2268 */
38 static guchar PT[] = {
39 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
40 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
41 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
42 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
43 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
44 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
45 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
46 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
47 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
48 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
49 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
50 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
51 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
52 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
53 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
54 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
55 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
56 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
57 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
58 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
59 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
60 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
61 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
62 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
63 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
64 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
65 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
66 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
67 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
68 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
69 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
70 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
71 };
72
73
74 /** prime number used in DH exchange */
75 static guchar dh_prime[] = {
76 0xCF, 0x84, 0xAF, 0xCE, 0x86, 0xDD, 0xFA, 0x52,
77 0x7F, 0x13, 0x6D, 0x10, 0x35, 0x75, 0x28, 0xEE,
78 0xFB, 0xA0, 0xAF, 0xEF, 0x80, 0x8F, 0x29, 0x17,
79 0x4E, 0x3B, 0x6A, 0x9E, 0x97, 0x00, 0x01, 0x71,
80 0x7C, 0x8F, 0x10, 0x6C, 0x41, 0xC1, 0x61, 0xA6,
81 0xCE, 0x91, 0x05, 0x7B, 0x34, 0xDA, 0x62, 0xCB,
82 0xB8, 0x7B, 0xFD, 0xC1, 0xB3, 0x5C, 0x1B, 0x91,
83 0x0F, 0xEA, 0x72, 0x24, 0x9D, 0x56, 0x6B, 0x9F
84 };
85
86
87 /** base used in DH exchange */
88 #define DH_BASE 3
89
90
mwMpi_new()91 struct mwMpi *mwMpi_new() {
92 struct mwMpi *i;
93 i = g_new0(struct mwMpi, 1);
94 mw_mp_init(&i->i);
95 return i;
96 }
97
98
mwMpi_free(struct mwMpi * i)99 void mwMpi_free(struct mwMpi *i) {
100 if(! i) return;
101 mw_mp_clear(&i->i);
102 g_free(i);
103 }
104
105
mwInitDHPrime(mw_mp_int * i)106 static void mwInitDHPrime(mw_mp_int *i) {
107 mw_mp_init(i);
108 mw_mp_read_unsigned_bin(i, dh_prime, 64);
109 }
110
111
mwMpi_setDHPrime(struct mwMpi * i)112 void mwMpi_setDHPrime(struct mwMpi *i) {
113 g_return_if_fail(i != NULL);
114 mw_mp_read_unsigned_bin(&i->i, dh_prime, 64);
115 }
116
117
mwInitDHBase(mw_mp_int * i)118 static void mwInitDHBase(mw_mp_int *i) {
119 mw_mp_init(i);
120 mw_mp_set_int(i, DH_BASE);
121 }
122
123
mwMpi_setDHBase(struct mwMpi * i)124 void mwMpi_setDHBase(struct mwMpi *i) {
125 g_return_if_fail(i != NULL);
126 mw_mp_set_int(&i->i, DH_BASE);
127 }
128
129
mw_mp_set_rand(mw_mp_int * i,guint bits)130 static void mw_mp_set_rand(mw_mp_int *i, guint bits) {
131 size_t len, l;
132 guchar *buf;
133
134 l = len = (bits / 8) + 1;
135 buf = g_malloc(len);
136
137 srand(time(NULL));
138 while(l--) buf[l] = rand() & 0xff;
139
140 buf[0] &= (0xff >> (8 - (bits % 8)));
141
142 mw_mp_read_unsigned_bin(i, buf, len);
143 g_free(buf);
144 }
145
146
mwDHRandKeypair(mw_mp_int * private_key,mw_mp_int * public_key)147 static void mwDHRandKeypair(mw_mp_int *private_key, mw_mp_int *public_key) {
148 mw_mp_int prime, base;
149
150 mwInitDHPrime(&prime);
151 mwInitDHBase(&base);
152
153 mw_mp_set_rand(private_key, 512);
154 mw_mp_exptmod(&base, private_key, &prime, public_key);
155
156 mw_mp_clear(&prime);
157 mw_mp_clear(&base);
158 }
159
160
mwMpi_randDHKeypair(struct mwMpi * private_key,struct mwMpi * public_key)161 void mwMpi_randDHKeypair(struct mwMpi *private_key, struct mwMpi *public_key) {
162 g_return_if_fail(private_key != NULL);
163 g_return_if_fail(public_key != NULL);
164
165 mwDHRandKeypair(&private_key->i, &public_key->i);
166 }
167
168
mwDHCalculateShared(mw_mp_int * shared_key,mw_mp_int * remote_key,mw_mp_int * private_key)169 static void mwDHCalculateShared(mw_mp_int *shared_key, mw_mp_int *remote_key,
170 mw_mp_int *private_key) {
171 mw_mp_int prime;
172
173 mwInitDHPrime(&prime);
174 mw_mp_exptmod(remote_key, private_key, &prime, shared_key);
175 mw_mp_clear(&prime);
176 }
177
178
mwMpi_calculateDHShared(struct mwMpi * shared_key,struct mwMpi * remote_key,struct mwMpi * private_key)179 void mwMpi_calculateDHShared(struct mwMpi *shared_key, struct mwMpi *remote_key,
180 struct mwMpi *private_key) {
181
182 g_return_if_fail(shared_key != NULL);
183 g_return_if_fail(remote_key != NULL);
184 g_return_if_fail(private_key != NULL);
185
186 mwDHCalculateShared(&shared_key->i, &remote_key->i, &private_key->i);
187 }
188
189
mwDHImportKey(mw_mp_int * key,struct mwOpaque * o)190 static void mwDHImportKey(mw_mp_int *key, struct mwOpaque *o) {
191 mw_mp_read_unsigned_bin(key, o->data, o->len);
192 }
193
194
mwMpi_import(struct mwMpi * i,struct mwOpaque * o)195 void mwMpi_import(struct mwMpi *i, struct mwOpaque *o) {
196 g_return_if_fail(i != NULL);
197 g_return_if_fail(o != NULL);
198
199 mwDHImportKey(&i->i, o);
200 }
201
202
mwDHExportKey(mw_mp_int * key,struct mwOpaque * o)203 static void mwDHExportKey(mw_mp_int *key, struct mwOpaque *o) {
204 o->len = mw_mp_unsigned_bin_size(key);
205 o->data = g_malloc0(o->len);
206 mw_mp_to_unsigned_bin(key, o->data);
207 }
208
209
mwMpi_export(struct mwMpi * i,struct mwOpaque * o)210 void mwMpi_export(struct mwMpi *i, struct mwOpaque *o) {
211 g_return_if_fail(i != NULL);
212 g_return_if_fail(o != NULL);
213
214 mwDHExportKey(&i->i, o);
215 }
216
217
mwKeyRandom(guchar * key,gsize keylen)218 void mwKeyRandom(guchar *key, gsize keylen) {
219 g_return_if_fail(key != NULL);
220
221 srand(time(NULL));
222 while(keylen--) key[keylen] = rand() & 0xff;
223 }
224
225
mwIV_init(guchar * iv)226 void mwIV_init(guchar *iv) {
227 iv[0] = 0x01;
228 iv[1] = 0x23;
229 iv[2] = 0x45;
230 iv[3] = 0x67;
231 iv[4] = 0x89;
232 iv[5] = 0xab;
233 iv[6] = 0xcd;
234 iv[7] = 0xef;
235 }
236
237
238 /* This does not seem to produce the same results as normal RC2 key
239 expansion would, but it works, so eh. It might be smart to farm
240 this out to mozilla or openssl */
mwKeyExpand(int * ekey,const guchar * key,gsize keylen)241 void mwKeyExpand(int *ekey, const guchar *key, gsize keylen) {
242 guchar tmp[128];
243 int i, j;
244
245 g_return_if_fail(keylen > 0);
246 g_return_if_fail(key != NULL);
247
248 if(keylen > 128) keylen = 128;
249
250 /* fill the first chunk with what key bytes we have */
251 for(i = keylen; i--; tmp[i] = key[i]);
252 /* memcpy(tmp, key, keylen); */
253
254 /* build the remaining key from the given data */
255 for(i = 0; keylen < 128; i++) {
256 tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ];
257 keylen++;
258 }
259
260 tmp[0] = PT[ tmp[0] & 0xff ];
261
262 for(i = 0, j = 0; i < 64; i++) {
263 ekey[i] = (tmp[j] & 0xff) | (tmp[j+1] << 8);
264 j += 2;
265 }
266 }
267
268
269 /* normal RC2 encryption given a full 128-byte (as 64 ints) key */
mwEncryptBlock(const int * ekey,guchar * out)270 static void mwEncryptBlock(const int *ekey, guchar *out) {
271
272 int a, b, c, d;
273 int i, j;
274
275 a = (out[7] << 8) | (out[6] & 0xff);
276 b = (out[5] << 8) | (out[4] & 0xff);
277 c = (out[3] << 8) | (out[2] & 0xff);
278 d = (out[1] << 8) | (out[0] & 0xff);
279
280 for(i = 0; i < 16; i++) {
281 j = i * 4;
282
283 d += ((c & (a ^ 0xffff)) + (b & a) + ekey[j++]);
284 d = (d << 1) | (d >> 15 & 0x0001);
285
286 c += ((b & (d ^ 0xffff)) + (a & d) + ekey[j++]);
287 c = (c << 2) | (c >> 14 & 0x0003);
288
289 b += ((a & (c ^ 0xffff)) + (d & c) + ekey[j++]);
290 b = (b << 3) | (b >> 13 & 0x0007);
291
292 a += ((d & (b ^ 0xffff)) + (c & b) + ekey[j++]);
293 a = (a << 5) | (a >> 11 & 0x001f);
294
295 if(i == 4 || i == 10) {
296 d += ekey[a & 0x003f];
297 c += ekey[d & 0x003f];
298 b += ekey[c & 0x003f];
299 a += ekey[b & 0x003f];
300 }
301 }
302
303 *out++ = d & 0xff;
304 *out++ = (d >> 8) & 0xff;
305 *out++ = c & 0xff;
306 *out++ = (c >> 8) & 0xff;
307 *out++ = b & 0xff;
308 *out++ = (b >> 8) & 0xff;
309 *out++ = a & 0xff;
310 *out++ = (a >> 8) & 0xff;
311 }
312
313
mwEncryptExpanded(const int * ekey,guchar * iv,struct mwOpaque * in_data,struct mwOpaque * out_data)314 void mwEncryptExpanded(const int *ekey, guchar *iv,
315 struct mwOpaque *in_data,
316 struct mwOpaque *out_data) {
317
318 guchar *i = in_data->data;
319 gsize i_len = in_data->len;
320
321 guchar *o;
322 gsize o_len;
323
324 int x, y;
325
326 /* pad upwards to a multiple of 8 */
327 /* o_len = (i_len & -8) + 8; */
328 o_len = i_len + (8 - (i_len % 8));
329 o = g_malloc(o_len);
330
331 out_data->data = o;
332 out_data->len = o_len;
333
334 /* figure out the amount of padding */
335 y = o_len - i_len;
336
337 /* copy in to out, and write padding bytes */
338 for(x = i_len; x--; o[x] = i[x]);
339 for(x = i_len; x < o_len; o[x++] = y);
340 /* memcpy(o, i, i_len);
341 memset(o + i_len, y, y); */
342
343 /* encrypt in blocks */
344 for(x = o_len; x > 0; x -= 8) {
345 for(y = 8; y--; o[y] ^= iv[y]);
346 mwEncryptBlock(ekey, o);
347 for(y = 8; y--; iv[y] = o[y]);
348 /* memcpy(iv, o, 8); */
349 o += 8;
350 }
351 }
352
353
mwEncrypt(const guchar * key,gsize keylen,guchar * iv,struct mwOpaque * in,struct mwOpaque * out)354 void mwEncrypt(const guchar *key, gsize keylen, guchar *iv,
355 struct mwOpaque *in, struct mwOpaque *out) {
356
357 int ekey[64];
358 mwKeyExpand(ekey, key, keylen);
359 mwEncryptExpanded(ekey, iv, in, out);
360 }
361
362
mwDecryptBlock(const int * ekey,guchar * out)363 static void mwDecryptBlock(const int *ekey, guchar *out) {
364
365 int a, b, c, d;
366 int i, j;
367
368 a = (out[7] << 8) | (out[6] & 0xff);
369 b = (out[5] << 8) | (out[4] & 0xff);
370 c = (out[3] << 8) | (out[2] & 0xff);
371 d = (out[1] << 8) | (out[0] & 0xff);
372
373 for(i = 16; i--; ) {
374 j = i * 4 + 3;
375
376 a = (a << 11) | (a >> 5 & 0x07ff);
377 a -= ((d & (b ^ 0xffff)) + (c & b) + ekey[j--]);
378
379 b = (b << 13) | (b >> 3 & 0x1fff);
380 b -= ((a & (c ^ 0xffff)) + (d & c) + ekey[j--]);
381
382 c = (c << 14) | (c >> 2 & 0x3fff);
383 c -= ((b & (d ^ 0xffff)) + (a & d) + ekey[j--]);
384
385 d = (d << 15) | (d >> 1 & 0x7fff);
386 d -= ((c & (a ^ 0xffff)) + (b & a) + ekey[j--]);
387
388 if(i == 5 || i == 11) {
389 a -= ekey[b & 0x003f];
390 b -= ekey[c & 0x003f];
391 c -= ekey[d & 0x003f];
392 d -= ekey[a & 0x003f];
393 }
394 }
395
396 *out++ = d & 0xff;
397 *out++ = (d >> 8) & 0xff;
398 *out++ = c & 0xff;
399 *out++ = (c >> 8) & 0xff;
400 *out++ = b & 0xff;
401 *out++ = (b >> 8) & 0xff;
402 *out++ = a & 0xff;
403 *out++ = (a >> 8) & 0xff;
404 }
405
406
mwDecryptExpanded(const int * ekey,guchar * iv,struct mwOpaque * in_data,struct mwOpaque * out_data)407 void mwDecryptExpanded(const int *ekey, guchar *iv,
408 struct mwOpaque *in_data,
409 struct mwOpaque *out_data) {
410
411 guchar *i = in_data->data;
412 gsize i_len = in_data->len;
413
414 guchar *o;
415 gsize o_len;
416
417 int x, y;
418
419 if(i_len % 8) {
420 /* this doesn't check to ensure that in_data->len is a multiple of
421 8, which is damn well ought to be. */
422 g_warning("attempting decryption of mis-sized data, %u bytes",
423 (guint) i_len);
424 }
425
426 o = g_malloc(i_len);
427 o_len = i_len;
428 for(x = i_len; x--; o[x] = i[x]);
429 /* memcpy(o, i, i_len); */
430
431 out_data->data = o;
432 out_data->len = o_len;
433
434 for(x = o_len; x > 0; x -= 8) {
435 /* decrypt a block */
436 mwDecryptBlock(ekey, o);
437
438 /* modify the initialization vector */
439 for(y = 8; y--; o[y] ^= iv[y]);
440 for(y = 8; y--; iv[y] = i[y]);
441 /* memcpy(iv, i, 8); */
442 i += 8;
443 o += 8;
444 }
445
446 /* shorten the length by the value of the filler in the padding
447 bytes */
448 out_data->len -= *(o - 1);
449 }
450
451
mwDecrypt(const guchar * key,gsize keylen,guchar * iv,struct mwOpaque * in,struct mwOpaque * out)452 void mwDecrypt(const guchar *key, gsize keylen, guchar *iv,
453 struct mwOpaque *in, struct mwOpaque *out) {
454
455 int ekey[64];
456 mwKeyExpand(ekey, key, keylen);
457 mwDecryptExpanded(ekey, iv, in, out);
458 }
459
460
461
462 struct mwCipher_RC2_40 {
463 struct mwCipher cipher;
464 int session_key[64];
465 gboolean ready;
466 };
467
468
469 struct mwCipherInstance_RC2_40 {
470 struct mwCipherInstance instance;
471 int incoming_key[64];
472 guchar outgoing_iv[8];
473 guchar incoming_iv[8];
474 };
475
476
get_name_RC2_40()477 static const char *get_name_RC2_40() {
478 return "RC2/40 Cipher";
479 }
480
481
get_desc_RC2_40()482 static const char *get_desc_RC2_40() {
483 return "RC2, 40-bit effective key";
484 }
485
486
encrypt_RC2_40(struct mwCipherInstance * ci,struct mwOpaque * data)487 static int encrypt_RC2_40(struct mwCipherInstance *ci,
488 struct mwOpaque *data) {
489
490 struct mwCipherInstance_RC2_40 *cir;
491 struct mwCipher_RC2_40 *cr;
492 struct mwOpaque o = { 0, 0 };
493
494 cir = (struct mwCipherInstance_RC2_40 *) ci;
495 cr = (struct mwCipher_RC2_40 *) ci->cipher;
496
497 mwEncryptExpanded(cr->session_key, cir->outgoing_iv, data, &o);
498
499 mwOpaque_clear(data);
500 data->data = o.data;
501 data->len = o.len;
502
503 return 0;
504 }
505
506
decrypt_RC2_40(struct mwCipherInstance * ci,struct mwOpaque * data)507 static int decrypt_RC2_40(struct mwCipherInstance *ci,
508 struct mwOpaque *data) {
509
510 struct mwCipherInstance_RC2_40 *cir;
511 struct mwCipher_RC2_40 *cr;
512 struct mwOpaque o = { 0, 0 };
513
514 cir = (struct mwCipherInstance_RC2_40 *) ci;
515 cr = (struct mwCipher_RC2_40 *) ci->cipher;
516
517 mwDecryptExpanded(cir->incoming_key, cir->incoming_iv, data, &o);
518
519 mwOpaque_clear(data);
520 data->data = o.data;
521 data->len = o.len;
522
523 return 0;
524 }
525
526
527 static struct mwCipherInstance *
new_instance_RC2_40(struct mwCipher * cipher,struct mwChannel * chan)528 new_instance_RC2_40(struct mwCipher *cipher,
529 struct mwChannel *chan) {
530
531 struct mwCipher_RC2_40 *cr;
532 struct mwCipherInstance_RC2_40 *cir;
533 struct mwCipherInstance *ci;
534
535 cr = (struct mwCipher_RC2_40 *) cipher;
536
537 /* a bit of lazy initialization here */
538 if(! cr->ready) {
539 struct mwLoginInfo *info = mwSession_getLoginInfo(cipher->session);
540 mwKeyExpand(cr->session_key, (guchar *) info->login_id, 5);
541 cr->ready = TRUE;
542 }
543
544 cir = g_new0(struct mwCipherInstance_RC2_40, 1);
545 ci = &cir->instance;
546
547 ci->cipher = cipher;
548 ci->channel = chan;
549
550 mwIV_init(cir->incoming_iv);
551 mwIV_init(cir->outgoing_iv);
552
553 return ci;
554 }
555
556
new_item_RC2_40(struct mwCipherInstance * ci)557 static struct mwEncryptItem *new_item_RC2_40(struct mwCipherInstance *ci) {
558 struct mwEncryptItem *e;
559
560 e = g_new0(struct mwEncryptItem, 1);
561 e->id = mwCipher_RC2_40;
562 return e;
563 }
564
565
566 static struct mwEncryptItem *
offer_RC2_40(struct mwCipherInstance * ci)567 offer_RC2_40(struct mwCipherInstance *ci) {
568 return new_item_RC2_40(ci);
569 }
570
571
accepted_RC2_40(struct mwCipherInstance * ci,struct mwEncryptItem * item)572 static void accepted_RC2_40(struct mwCipherInstance *ci,
573 struct mwEncryptItem *item) {
574
575 struct mwCipherInstance_RC2_40 *cir;
576 struct mwLoginInfo *info;
577
578 cir = (struct mwCipherInstance_RC2_40 *) ci;
579 info = mwChannel_getUser(ci->channel);
580
581 if(info->login_id) {
582 mwKeyExpand(cir->incoming_key, (guchar *) info->login_id, 5);
583 }
584 }
585
586
587 static struct mwEncryptItem *
accept_RC2_40(struct mwCipherInstance * ci)588 accept_RC2_40(struct mwCipherInstance *ci) {
589
590 accepted_RC2_40(ci, NULL);
591 return new_item_RC2_40(ci);
592 }
593
594
mwCipher_new_RC2_40(struct mwSession * s)595 struct mwCipher *mwCipher_new_RC2_40(struct mwSession *s) {
596 struct mwCipher_RC2_40 *cr = g_new0(struct mwCipher_RC2_40, 1);
597 struct mwCipher *c = &cr->cipher;
598
599 c->session = s;
600 c->type = mwCipher_RC2_40;
601 c->get_name = get_name_RC2_40;
602 c->get_desc = get_desc_RC2_40;
603 c->new_instance = new_instance_RC2_40;
604
605 c->offer = offer_RC2_40;
606
607 c->accepted = accepted_RC2_40;
608 c->accept = accept_RC2_40;
609
610 c->encrypt = encrypt_RC2_40;
611 c->decrypt = decrypt_RC2_40;
612
613 return c;
614 }
615
616
617 struct mwCipher_RC2_128 {
618 struct mwCipher cipher;
619 mw_mp_int private_key;
620 struct mwOpaque public_key;
621 };
622
623
624 struct mwCipherInstance_RC2_128 {
625 struct mwCipherInstance instance;
626 int shared[64]; /* shared secret determined via DH exchange */
627 guchar outgoing_iv[8];
628 guchar incoming_iv[8];
629 };
630
631
get_name_RC2_128()632 static const char *get_name_RC2_128() {
633 return "RC2/128 Cipher";
634 }
635
636
get_desc_RC2_128()637 static const char *get_desc_RC2_128() {
638 return "RC2, DH shared secret key";
639 }
640
641
642 static struct mwCipherInstance *
new_instance_RC2_128(struct mwCipher * cipher,struct mwChannel * chan)643 new_instance_RC2_128(struct mwCipher *cipher,
644 struct mwChannel *chan) {
645
646 struct mwCipher_RC2_128 *cr;
647 struct mwCipherInstance_RC2_128 *cir;
648 struct mwCipherInstance *ci;
649
650 cr = (struct mwCipher_RC2_128 *) cipher;
651
652 cir = g_new0(struct mwCipherInstance_RC2_128, 1);
653 ci = &cir->instance;
654
655 ci->cipher = cipher;
656 ci->channel = chan;
657
658 mwIV_init(cir->incoming_iv);
659 mwIV_init(cir->outgoing_iv);
660
661 return ci;
662 }
663
664
offered_RC2_128(struct mwCipherInstance * ci,struct mwEncryptItem * item)665 static void offered_RC2_128(struct mwCipherInstance *ci,
666 struct mwEncryptItem *item) {
667
668 mw_mp_int remote_key;
669 mw_mp_int shared;
670 struct mwOpaque sho = { 0, 0 };
671
672 struct mwCipher *c;
673 struct mwCipher_RC2_128 *cr;
674 struct mwCipherInstance_RC2_128 *cir;
675
676 c = ci->cipher;
677 cr = (struct mwCipher_RC2_128 *) c;
678 cir = (struct mwCipherInstance_RC2_128 *) ci;
679
680 mw_mp_init(&remote_key);
681 mw_mp_init(&shared);
682
683 mwDHImportKey(&remote_key, &item->info);
684 mwDHCalculateShared(&shared, &remote_key, &cr->private_key);
685 mwDHExportKey(&shared, &sho);
686
687 /* key expanded from the last 16 bytes of the DH shared secret. This
688 took me forever to figure out. 16 bytes is 128 bit. */
689 /* the sh_len-16 is important, because the key len could
690 hypothetically start with 8bits or more unset, meaning the
691 exported key might be less than 64 bytes in length */
692 mwKeyExpand(cir->shared, sho.data+(sho.len-16), 16);
693
694 mw_mp_clear(&remote_key);
695 mw_mp_clear(&shared);
696 mwOpaque_clear(&sho);
697 }
698
699
700 static struct mwEncryptItem *
offer_RC2_128(struct mwCipherInstance * ci)701 offer_RC2_128(struct mwCipherInstance *ci) {
702
703 struct mwCipher *c;
704 struct mwCipher_RC2_128 *cr;
705 struct mwEncryptItem *ei;
706
707 c = ci->cipher;
708 cr = (struct mwCipher_RC2_128 *) c;
709
710 ei = g_new0(struct mwEncryptItem, 1);
711 ei->id = mwCipher_RC2_128;
712 mwOpaque_clone(&ei->info, &cr->public_key);
713
714 return ei;
715 }
716
717
accepted_RC2_128(struct mwCipherInstance * ci,struct mwEncryptItem * item)718 static void accepted_RC2_128(struct mwCipherInstance *ci,
719 struct mwEncryptItem *item) {
720
721 return offered_RC2_128(ci, item);
722 }
723
724
725 static struct mwEncryptItem *
accept_RC2_128(struct mwCipherInstance * ci)726 accept_RC2_128(struct mwCipherInstance *ci) {
727
728 return offer_RC2_128(ci);
729 }
730
731
encrypt_RC2_128(struct mwCipherInstance * ci,struct mwOpaque * data)732 static int encrypt_RC2_128(struct mwCipherInstance *ci,
733 struct mwOpaque *data) {
734
735 struct mwCipherInstance_RC2_128 *cir;
736 struct mwOpaque o = { 0, 0 };
737
738 cir = (struct mwCipherInstance_RC2_128 *) ci;
739
740 mwEncryptExpanded(cir->shared, cir->outgoing_iv, data, &o);
741
742 mwOpaque_clear(data);
743 data->data = o.data;
744 data->len = o.len;
745
746 return 0;
747 }
748
749
decrypt_RC2_128(struct mwCipherInstance * ci,struct mwOpaque * data)750 static int decrypt_RC2_128(struct mwCipherInstance *ci,
751 struct mwOpaque *data) {
752
753 struct mwCipherInstance_RC2_128 *cir;
754 struct mwOpaque o = { 0, 0 };
755
756 cir = (struct mwCipherInstance_RC2_128 *) ci;
757
758 mwDecryptExpanded(cir->shared, cir->incoming_iv, data, &o);
759
760 mwOpaque_clear(data);
761 data->data = o.data;
762 data->len = o.len;
763
764 return 0;
765 }
766
767
clear_RC2_128(struct mwCipher * c)768 static void clear_RC2_128(struct mwCipher *c) {
769 struct mwCipher_RC2_128 *cr;
770 cr = (struct mwCipher_RC2_128 *) c;
771
772 mw_mp_clear(&cr->private_key);
773 mwOpaque_clear(&cr->public_key);
774 }
775
776
mwCipher_new_RC2_128(struct mwSession * s)777 struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s) {
778 struct mwCipher_RC2_128 *cr;
779 struct mwCipher *c;
780
781 mw_mp_int pubkey;
782
783 cr = g_new0(struct mwCipher_RC2_128, 1);
784 c = &cr->cipher;
785
786 c->session = s;
787 c->type = mwCipher_RC2_128;
788 c->get_name = get_name_RC2_128;
789 c->get_desc = get_desc_RC2_128;
790 c->new_instance = new_instance_RC2_128;
791
792 c->offered = offered_RC2_128;
793 c->offer = offer_RC2_128;
794
795 c->accepted = accepted_RC2_128;
796 c->accept = accept_RC2_128;
797
798 c->encrypt = encrypt_RC2_128;
799 c->decrypt = decrypt_RC2_128;
800
801 c->clear = clear_RC2_128;
802
803 mw_mp_init(&cr->private_key);
804 mw_mp_init(&pubkey);
805 mwDHRandKeypair(&cr->private_key, &pubkey);
806 mwDHExportKey(&pubkey, &cr->public_key);
807 mw_mp_clear(&pubkey);
808
809 return c;
810 }
811
812
mwCipher_getSession(struct mwCipher * cipher)813 struct mwSession *mwCipher_getSession(struct mwCipher *cipher) {
814 g_return_val_if_fail(cipher != NULL, NULL);
815 return cipher->session;
816 }
817
818
mwCipher_getType(struct mwCipher * cipher)819 guint16 mwCipher_getType(struct mwCipher *cipher) {
820 /* oh man, this is a bad failover... who the hell decided to make
821 zero a real cipher id? */
822 g_return_val_if_fail(cipher != NULL, 0xffff);
823 return cipher->type;
824 }
825
826
mwCipher_getName(struct mwCipher * cipher)827 const char *mwCipher_getName(struct mwCipher *cipher) {
828 g_return_val_if_fail(cipher != NULL, NULL);
829 g_return_val_if_fail(cipher->get_name != NULL, NULL);
830 return cipher->get_name();
831 }
832
833
mwCipher_getDesc(struct mwCipher * cipher)834 const char *mwCipher_getDesc(struct mwCipher *cipher) {
835 g_return_val_if_fail(cipher != NULL, NULL);
836 g_return_val_if_fail(cipher->get_desc != NULL, NULL);
837 return cipher->get_desc();
838 }
839
840
mwCipher_free(struct mwCipher * cipher)841 void mwCipher_free(struct mwCipher *cipher) {
842 if(! cipher) return;
843
844 if(cipher->clear)
845 cipher->clear(cipher);
846
847 g_free(cipher);
848 }
849
850
mwCipher_newInstance(struct mwCipher * cipher,struct mwChannel * chan)851 struct mwCipherInstance *mwCipher_newInstance(struct mwCipher *cipher,
852 struct mwChannel *chan) {
853 g_return_val_if_fail(cipher != NULL, NULL);
854 g_return_val_if_fail(chan != NULL, NULL);
855 g_return_val_if_fail(cipher->new_instance != NULL, NULL);
856 return cipher->new_instance(cipher, chan);
857 }
858
859
mwCipherInstance_getCipher(struct mwCipherInstance * ci)860 struct mwCipher *mwCipherInstance_getCipher(struct mwCipherInstance *ci) {
861 g_return_val_if_fail(ci != NULL, NULL);
862 return ci->cipher;
863 }
864
865
mwCipherInstance_getChannel(struct mwCipherInstance * ci)866 struct mwChannel *mwCipherInstance_getChannel(struct mwCipherInstance *ci) {
867 g_return_val_if_fail(ci != NULL, NULL);
868 return ci->channel;
869 }
870
871
mwCipherInstance_offered(struct mwCipherInstance * ci,struct mwEncryptItem * item)872 void mwCipherInstance_offered(struct mwCipherInstance *ci,
873 struct mwEncryptItem *item) {
874 struct mwCipher *cipher;
875
876 g_return_if_fail(ci != NULL);
877
878 cipher = ci->cipher;
879 g_return_if_fail(cipher != NULL);
880
881 if(cipher->offered) cipher->offered(ci, item);
882 }
883
884
885 struct mwEncryptItem *
mwCipherInstance_offer(struct mwCipherInstance * ci)886 mwCipherInstance_offer(struct mwCipherInstance *ci) {
887 struct mwCipher *cipher;
888
889 g_return_val_if_fail(ci != NULL, NULL);
890
891 cipher = ci->cipher;
892 g_return_val_if_fail(cipher != NULL, NULL);
893
894 return cipher->offer(ci);
895 }
896
897
mwCipherInstance_accepted(struct mwCipherInstance * ci,struct mwEncryptItem * item)898 void mwCipherInstance_accepted(struct mwCipherInstance *ci,
899 struct mwEncryptItem *item) {
900 struct mwCipher *cipher;
901
902 g_return_if_fail(ci != NULL);
903
904 cipher = ci->cipher;
905 g_return_if_fail(cipher != NULL);
906
907 if(cipher->accepted) cipher->accepted(ci, item);
908 }
909
910
911 struct mwEncryptItem *
mwCipherInstance_accept(struct mwCipherInstance * ci)912 mwCipherInstance_accept(struct mwCipherInstance *ci) {
913 struct mwCipher *cipher;
914
915 g_return_val_if_fail(ci != NULL, NULL);
916
917 cipher = ci->cipher;
918 g_return_val_if_fail(cipher != NULL, NULL);
919
920 return cipher->accept(ci);
921 }
922
923
mwCipherInstance_encrypt(struct mwCipherInstance * ci,struct mwOpaque * data)924 int mwCipherInstance_encrypt(struct mwCipherInstance *ci,
925 struct mwOpaque *data) {
926 struct mwCipher *cipher;
927
928 g_return_val_if_fail(data != NULL, 0);
929
930 if(! ci) return 0;
931 cipher = ci->cipher;
932
933 g_return_val_if_fail(cipher != NULL, -1);
934
935 return (cipher->encrypt)?
936 cipher->encrypt(ci, data): 0;
937 }
938
939
mwCipherInstance_decrypt(struct mwCipherInstance * ci,struct mwOpaque * data)940 int mwCipherInstance_decrypt(struct mwCipherInstance *ci,
941 struct mwOpaque *data) {
942 struct mwCipher *cipher;
943
944 g_return_val_if_fail(data != NULL, 0);
945
946 if(! ci) return 0;
947 cipher = ci->cipher;
948
949 g_return_val_if_fail(cipher != NULL, -1);
950
951 return (cipher->decrypt)?
952 cipher->decrypt(ci, data): 0;
953 }
954
955
mwCipherInstance_free(struct mwCipherInstance * ci)956 void mwCipherInstance_free(struct mwCipherInstance *ci) {
957 struct mwCipher *cipher;
958
959 if(! ci) return;
960
961 cipher = ci->cipher;
962
963 if(cipher && cipher->clear_instance)
964 cipher->clear_instance(ci);
965
966 g_free(ci);
967 }
968
969