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