comparison src/protocols/sametime/meanwhile/cipher.c @ 12261:2edf5dc1b2ea

[gaim-migrate @ 14563] Removed the dependancy on libgmp, opting to use the public domain libmpi code instead. Bringing over updates to the places service which should fix some crash bugs. committer: Tailor Script <tailor@pidgin.im>
author Christopher O'Brien <siege@pidgin.im>
date Tue, 29 Nov 2005 23:31:40 +0000
parents 0110fc7c6a8a
children a2ebf585d8c6
comparison
equal deleted inserted replaced
12260:0a9574ed62cd 12261:2edf5dc1b2ea
17 License along with this library; if not, write to the Free 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 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #include <stdlib.h> 21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h> 22 #include <time.h>
24 23
25 #include <gmp.h> 24 #include "mpi/mpi.h"
26
27 25
28 #include "mw_channel.h" 26 #include "mw_channel.h"
29 #include "mw_cipher.h" 27 #include "mw_cipher.h"
30 #include "mw_debug.h" 28 #include "mw_debug.h"
31 #include "mw_session.h" 29 #include "mw_session.h"
30
31
32 struct mwMpi {
33 mp_int i;
34 };
32 35
33 36
34 /** From RFC2268 */ 37 /** From RFC2268 */
35 static unsigned char PT[] = { 38 static unsigned char PT[] = {
36 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 39 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
83 86
84 /** base used in DH exchange */ 87 /** base used in DH exchange */
85 #define DH_BASE 3 88 #define DH_BASE 3
86 89
87 90
88 void mwInitDHPrime(mpz_t z) { 91 struct mwMpi *mwMpi_new() {
89 mpz_init(z); 92 struct mwMpi *i;
90 mpz_import(z, 64, 1, 1, 0, 0, dh_prime); 93 i = g_new0(struct mwMpi, 1);
91 } 94 mp_init(&i->i);
92 95 return i;
93 96 }
94 void mwInitDHBase(mpz_t z) { 97
95 mpz_init_set_ui(z, DH_BASE); 98
96 } 99 void mwMpi_free(struct mwMpi *i) {
97 100 if(! i) return;
98 101 mp_clear(&i->i);
99 void mwDHRandKeypair(mpz_t private, mpz_t public) { 102 g_free(i);
100 gmp_randstate_t rstate; 103 }
101 mpz_t prime, base; 104
105
106 static void mwInitDHPrime(mp_int *i) {
107 mp_init(i);
108 mp_read_unsigned_bin(i, dh_prime, 64);
109 }
110
111
112 void mwMpi_setDHPrime(struct mwMpi *i) {
113 g_return_if_fail(i != NULL);
114 mp_read_unsigned_bin(&i->i, dh_prime, 64);
115 }
116
117
118 static void mwInitDHBase(mp_int *i) {
119 mp_init(i);
120 mp_set_int(i, DH_BASE);
121 }
122
123
124 void mwMpi_setDHBase(struct mwMpi *i) {
125 g_return_if_fail(i != NULL);
126 mp_set_int(&i->i, DH_BASE);
127 }
128
129
130 static void mp_set_rand(mp_int *i, guint bits) {
131 size_t len, l;
132 unsigned char *buf;
133
134 l = len = (bits / 8) + 1;
135 buf = g_malloc(len);
136
137 srand(clock());
138 while(l--) buf[l] = rand() & 0xff;
139
140 buf[0] &= (0xff >> (8 - (bits % 8)));
141
142 mp_read_unsigned_bin(i, buf, len);
143 g_free(buf);
144 }
145
146
147 void mwMpi_rand(struct mwMpi *i, guint bits) {
148 g_return_if_fail(i != NULL);
149 mp_set_rand(&i->i, bits);
150 }
151
152
153 static void mwDHRandKeypair(mp_int *private, mp_int *public) {
154 mp_int prime, base;
102 155
103 mwInitDHPrime(prime); 156 mwInitDHPrime(&prime);
104 mwInitDHBase(base); 157 mwInitDHBase(&base);
105 158
106 gmp_randinit_default(rstate); 159 mp_set_rand(private, 512);
107 mpz_urandomb(private, rstate, 512); 160 mp_exptmod(&base, private, &prime, public);
108 mpz_powm(public, base, private, prime); 161
109 162 mp_clear(&prime);
110 mpz_clear(prime); 163 mp_clear(&base);
111 mpz_clear(base); 164 }
112 gmp_randclear(rstate); 165
113 } 166
114 167 void mwMpi_randDHKeypair(struct mwMpi *private, struct mwMpi *public) {
115 168 g_return_if_fail(private != NULL);
116 void mwDHCalculateShared(mpz_t shared, mpz_t remote, mpz_t private) { 169 g_return_if_fail(public != NULL);
117 mpz_t prime; 170
171 mwDHRandKeypair(&private->i, &public->i);
172 }
173
174
175 static void mwDHCalculateShared(mp_int *shared, mp_int *remote,
176 mp_int *private) {
177 mp_int prime;
118 178
119 mwInitDHPrime(prime); 179 mwInitDHPrime(&prime);
120 mpz_powm(shared, remote, private, prime); 180 mp_exptmod(remote, private, &prime, shared);
121 mpz_clear(prime); 181 mp_clear(&prime);
122 } 182 }
123 183
124 184
125 void mwDHImportKey(mpz_t key, struct mwOpaque *o) { 185 void mwMpi_calculateDHShared(struct mwMpi *shared, struct mwMpi *remote,
186 struct mwMpi *private) {
187
188 g_return_if_fail(shared != NULL);
189 g_return_if_fail(remote != NULL);
190 g_return_if_fail(private != NULL);
191
192 mwDHCalculateShared(&shared->i, &remote->i, &private->i);
193 }
194
195
196 static void mwDHImportKey(mp_int *key, struct mwOpaque *o) {
197 mp_read_unsigned_bin(key, o->data, o->len);
198 }
199
200
201 void mwMpi_import(struct mwMpi *i, struct mwOpaque *o) {
202 g_return_if_fail(i != NULL);
126 g_return_if_fail(o != NULL); 203 g_return_if_fail(o != NULL);
127 mpz_import(key, o->len, 1, 1, 1, 0, o->data); 204
128 } 205 mwDHImportKey(&i->i, o);
129 206 }
130 207
131 void mwDHExportKey(mpz_t key, struct mwOpaque *o) { 208
132 gsize needed; 209 static void mwDHExportKey(mp_int *key, struct mwOpaque *o) {
133 210 o->len = mp_unsigned_bin_size(key);
211 o->data = g_malloc0(o->len);
212 mp_to_unsigned_bin(key, o->data);
213 }
214
215
216 void mwMpi_export(struct mwMpi *i, struct mwOpaque *o) {
217 g_return_if_fail(i != NULL);
134 g_return_if_fail(o != NULL); 218 g_return_if_fail(o != NULL);
135 219
136 needed = (mpz_sizeinbase(key,2) + 7) / 8; 220 mwDHExportKey(&i->i, o);
137 o->len = 65; 221 }
138 o->data = g_malloc0(o->len); 222
139 223
140 mpz_export(o->data+(o->len-needed), NULL, 1, 1, 1, 0, key); 224 void mwKeyRandom(unsigned char *key, gsize keylen) {
141 }
142
143
144 void mwKeyRandom(char *key, gsize keylen) {
145 g_return_if_fail(key != NULL); 225 g_return_if_fail(key != NULL);
146 226
147 srand(clock()); 227 srand(clock());
148 while(keylen--) key[keylen] = rand() & 0xff; 228 while(keylen--) key[keylen] = rand() & 0xff;
149 } 229 }
150 230
151 231
152 void mwIV_init(char *iv) { 232 void mwIV_init(unsigned char *iv) {
233 int i;
153 static unsigned char normal_iv[] = { 234 static unsigned char normal_iv[] = {
154 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef 235 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
155 }; 236 };
156 memcpy(iv, normal_iv, 8); 237 for(i = 8; i--; iv[i] = normal_iv[i]);
238 /* memcpy(iv, normal_iv, 8); */
157 } 239 }
158 240
159 241
160 /* This does not seem to produce the same results as normal RC2 key 242 /* This does not seem to produce the same results as normal RC2 key
161 expansion would, but it works, so eh. It might be smart to farm 243 expansion would, but it works, so eh. It might be smart to farm
162 this out to mozilla or openssl */ 244 this out to mozilla or openssl */
163 void mwKeyExpand(int *ekey, const char *key, gsize keylen) { 245 void mwKeyExpand(int *ekey, const char *key, gsize keylen) {
164 char tmp[128]; 246 unsigned char tmp[128];
165 int i, j; 247 int i, j;
166 248
167 g_return_if_fail(keylen > 0); 249 g_return_if_fail(keylen > 0);
168 g_return_if_fail(key != NULL); 250 g_return_if_fail(key != NULL);
169 251
170 if(keylen > 128) keylen = 128; 252 if(keylen > 128) keylen = 128;
171 253
172 /* fill the first chunk with what key bytes we have */ 254 /* fill the first chunk with what key bytes we have */
173 memcpy(tmp, key, keylen); 255 for(i = keylen; i--; tmp[i] = key[i]);
256 /* memcpy(tmp, key, keylen); */
174 257
175 /* build the remaining key from the given data */ 258 /* build the remaining key from the given data */
176 for(i = 0; keylen < 128; i++) { 259 for(i = 0; keylen < 128; i++) {
177 tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ]; 260 tmp[keylen] = PT[ (tmp[keylen - 1] + tmp[i]) & 0xff ];
178 keylen++; 261 keylen++;
230 *out++ = a & 0xff; 313 *out++ = a & 0xff;
231 *out++ = (a >> 8) & 0xff; 314 *out++ = (a >> 8) & 0xff;
232 } 315 }
233 316
234 317
235 void mwEncryptExpanded(const int *ekey, char *iv, 318 void mwEncryptExpanded(const int *ekey, unsigned char *iv,
236 struct mwOpaque *in_data, 319 struct mwOpaque *in_data,
237 struct mwOpaque *out_data) { 320 struct mwOpaque *out_data) {
238 321
239 char *i = in_data->data; 322 unsigned char *i = in_data->data;
240 gsize i_len = in_data->len; 323 gsize i_len = in_data->len;
241 324
242 char *o; 325 unsigned char *o;
243 gsize o_len; 326 gsize o_len;
244 327
245 int x, y; 328 int x, y;
246 329
247 /* pad upwards to a multiple of 8 */ 330 /* pad upwards to a multiple of 8 */
253 336
254 /* figure out the amount of padding */ 337 /* figure out the amount of padding */
255 y = o_len - i_len; 338 y = o_len - i_len;
256 339
257 /* copy in to out, and write padding bytes */ 340 /* copy in to out, and write padding bytes */
258 memcpy(o, i, i_len); 341 for(x = i_len; x--; o[x] = i[x]);
259 memset(o + i_len, y, y); 342 for(x = i_len; x < o_len; o[x++] = y);
343 /* memcpy(o, i, i_len);
344 memset(o + i_len, y, y); */
260 345
261 /* encrypt in blocks */ 346 /* encrypt in blocks */
262 for(x = o_len; x > 0; x -= 8) { 347 for(x = o_len; x > 0; x -= 8) {
263 for(y = 8; y--; o[y] ^= iv[y]); 348 for(y = 8; y--; o[y] ^= iv[y]);
264 mwEncryptBlock(ekey, o); 349 mwEncryptBlock(ekey, o);
265 memcpy(iv, o, 8); 350 for(y = 8; y--; iv[y] = o[y]);
351 /* memcpy(iv, o, 8); */
266 o += 8; 352 o += 8;
267 } 353 }
268 } 354 }
269 355
270 356
271 void mwEncrypt(const char *key, gsize keylen, char *iv, 357 void mwEncrypt(const char *key, gsize keylen, unsigned char *iv,
272 struct mwOpaque *in, struct mwOpaque *out) { 358 struct mwOpaque *in, struct mwOpaque *out) {
273 359
274 int ekey[64]; 360 int ekey[64];
275 mwKeyExpand(ekey, key, keylen); 361 mwKeyExpand(ekey, key, keylen);
276 mwEncryptExpanded(ekey, iv, in, out); 362 mwEncryptExpanded(ekey, iv, in, out);
277 } 363 }
278 364
279 365
280 static void mwDecryptBlock(const int *ekey, char *out) { 366 static void mwDecryptBlock(const int *ekey, unsigned char *out) {
281 367
282 int a, b, c, d; 368 int a, b, c, d;
283 int i, j; 369 int i, j;
284 370
285 a = (out[7] << 8) | (out[6] & 0xff); 371 a = (out[7] << 8) | (out[6] & 0xff);
319 *out++ = a & 0xff; 405 *out++ = a & 0xff;
320 *out++ = (a >> 8) & 0xff; 406 *out++ = (a >> 8) & 0xff;
321 } 407 }
322 408
323 409
324 void mwDecryptExpanded(const int *ekey, char *iv, 410 void mwDecryptExpanded(const int *ekey, unsigned char *iv,
325 struct mwOpaque *in_data, 411 struct mwOpaque *in_data,
326 struct mwOpaque *out_data) { 412 struct mwOpaque *out_data) {
327 413
328 char *i = in_data->data; 414 unsigned char *i = in_data->data;
329 gsize i_len = in_data->len; 415 gsize i_len = in_data->len;
330 416
331 char *o; 417 unsigned char *o;
332 gsize o_len; 418 gsize o_len;
333 419
334 int x, y; 420 int x, y;
335 421
336 /* this doesn't check to ensure that in_data->len is a multiple of 422 /* this doesn't check to ensure that in_data->len is a multiple of
337 8, which is damn well ought to be. */ 423 8, which is damn well ought to be. */
338 424
339 o = g_malloc(i_len); 425 o = g_malloc(i_len);
340 o_len = i_len; 426 o_len = i_len;
341 memcpy(o, i, i_len); 427 for(x = i_len; x--; o[x] = i[x]);
428 /* memcpy(o, i, i_len); */
342 429
343 out_data->data = o; 430 out_data->data = o;
344 out_data->len = o_len; 431 out_data->len = o_len;
345 432
346 for(x = o_len; x > 0; x -= 8) { 433 for(x = o_len; x > 0; x -= 8) {
347 /* decrypt a block */ 434 /* decrypt a block */
348 mwDecryptBlock(ekey, o); 435 mwDecryptBlock(ekey, o);
349 436
350 /* modify the initialization vector */ 437 /* modify the initialization vector */
351 for(y = 8; y--; o[y] ^= iv[y]); 438 for(y = 8; y--; o[y] ^= iv[y]);
352 memcpy(iv, i, 8); 439 for(y = 8; y--; iv[y] = i[y]);
440 /* memcpy(iv, i, 8); */
353 i += 8; 441 i += 8;
354 o += 8; 442 o += 8;
355 } 443 }
356 444
357 /* shorten the length by the value of the filler in the padding 445 /* shorten the length by the value of the filler in the padding
358 bytes */ 446 bytes */
359 out_data->len -= *(o - 1); 447 out_data->len -= *(o - 1);
360 } 448 }
361 449
362 450
363 void mwDecrypt(const char *key, gsize keylen, char *iv, 451 void mwDecrypt(const char *key, gsize keylen, unsigned char *iv,
364 struct mwOpaque *in, struct mwOpaque *out) { 452 struct mwOpaque *in, struct mwOpaque *out) {
365 453
366 int ekey[64]; 454 int ekey[64];
367 mwKeyExpand(ekey, key, keylen); 455 mwKeyExpand(ekey, key, keylen);
368 mwDecryptExpanded(ekey, iv, in, out); 456 mwDecryptExpanded(ekey, iv, in, out);
378 466
379 467
380 struct mwCipherInstance_RC2_40 { 468 struct mwCipherInstance_RC2_40 {
381 struct mwCipherInstance instance; 469 struct mwCipherInstance instance;
382 int incoming_key[64]; 470 int incoming_key[64];
383 char outgoing_iv[8]; 471 unsigned char outgoing_iv[8];
384 char incoming_iv[8]; 472 unsigned char incoming_iv[8];
385 }; 473 };
386 474
387 475
388 static const char *get_name_RC2_40() { 476 static const char *get_name_RC2_40() {
389 return "RC2/40 Cipher"; 477 return "RC2/40 Cipher";
525 } 613 }
526 614
527 615
528 struct mwCipher_RC2_128 { 616 struct mwCipher_RC2_128 {
529 struct mwCipher cipher; 617 struct mwCipher cipher;
530 mpz_t private_key; 618 mp_int private_key;
531 struct mwOpaque public_key; 619 struct mwOpaque public_key;
532 }; 620 };
533 621
534 622
535 struct mwCipherInstance_RC2_128 { 623 struct mwCipherInstance_RC2_128 {
536 struct mwCipherInstance instance; 624 struct mwCipherInstance instance;
537 int shared[64]; /* shared secret determined via DH exchange */ 625 int shared[64]; /* shared secret determined via DH exchange */
538 char outgoing_iv[8]; 626 unsigned char outgoing_iv[8];
539 char incoming_iv[8]; 627 unsigned char incoming_iv[8];
540 }; 628 };
541 629
542 630
543 static const char *get_name_RC2_128() { 631 static const char *get_name_RC2_128() {
544 return "RC2/128 Cipher"; 632 return "RC2/128 Cipher";
574 662
575 663
576 static void offered_RC2_128(struct mwCipherInstance *ci, 664 static void offered_RC2_128(struct mwCipherInstance *ci,
577 struct mwEncryptItem *item) { 665 struct mwEncryptItem *item) {
578 666
579 mpz_t remote_key; 667 mp_int remote_key;
580 mpz_t shared; 668 mp_int shared;
581 struct mwOpaque sho = { 0, 0 }; 669 struct mwOpaque sho = { 0, 0 };
582 670
583 struct mwCipher *c; 671 struct mwCipher *c;
584 struct mwCipher_RC2_128 *cr; 672 struct mwCipher_RC2_128 *cr;
585 struct mwCipherInstance_RC2_128 *cir; 673 struct mwCipherInstance_RC2_128 *cir;
586 674
587 c = ci->cipher; 675 c = ci->cipher;
588 cr = (struct mwCipher_RC2_128 *) c; 676 cr = (struct mwCipher_RC2_128 *) c;
589 cir = (struct mwCipherInstance_RC2_128 *) ci; 677 cir = (struct mwCipherInstance_RC2_128 *) ci;
590 678
591 mpz_init(remote_key); 679 mp_init(&remote_key);
592 mpz_init(shared); 680 mp_init(&shared);
593 681
594 mwDHImportKey(remote_key, &item->info); 682 mwDHImportKey(&remote_key, &item->info);
595 mwDHCalculateShared(shared, remote_key, cr->private_key); 683 mwDHCalculateShared(&shared, &remote_key, &cr->private_key);
596 mwDHExportKey(shared, &sho); 684 mwDHExportKey(&shared, &sho);
597 685
598 /* key expanded from the last 16 bytes of the DH shared secret. This 686 /* key expanded from the last 16 bytes of the DH shared secret. This
599 took me forever to figure out. 16 bytes is 128 bit. */ 687 took me forever to figure out. 16 bytes is 128 bit. */
600 /* the sh_len-16 is important, because the key len could 688 /* the sh_len-16 is important, because the key len could
601 hypothetically start with 8bits or more unset, meaning the 689 hypothetically start with 8bits or more unset, meaning the
602 exported key might be less than 64 bytes in length */ 690 exported key might be less than 64 bytes in length */
603 mwKeyExpand(cir->shared, sho.data+(sho.len-16), 16); 691 mwKeyExpand(cir->shared, sho.data+(sho.len-16), 16);
604 692
605 mpz_clear(remote_key); 693 mp_clear(&remote_key);
606 mpz_clear(shared); 694 mp_clear(&shared);
607 mwOpaque_clear(&sho); 695 mwOpaque_clear(&sho);
608 } 696 }
609 697
610 698
611 static struct mwEncryptItem * 699 static struct mwEncryptItem *
678 766
679 static void clear_RC2_128(struct mwCipher *c) { 767 static void clear_RC2_128(struct mwCipher *c) {
680 struct mwCipher_RC2_128 *cr; 768 struct mwCipher_RC2_128 *cr;
681 cr = (struct mwCipher_RC2_128 *) c; 769 cr = (struct mwCipher_RC2_128 *) c;
682 770
683 mpz_clear(cr->private_key); 771 mp_clear(&cr->private_key);
684 mwOpaque_clear(&cr->public_key); 772 mwOpaque_clear(&cr->public_key);
685 } 773 }
686 774
687 775
688 struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s) { 776 struct mwCipher *mwCipher_new_RC2_128(struct mwSession *s) {
689 struct mwCipher_RC2_128 *cr; 777 struct mwCipher_RC2_128 *cr;
690 struct mwCipher *c; 778 struct mwCipher *c;
691 779
692 mpz_t pubkey; 780 mp_int pubkey;
693 781
694 cr = g_new0(struct mwCipher_RC2_128, 1); 782 cr = g_new0(struct mwCipher_RC2_128, 1);
695 c = &cr->cipher; 783 c = &cr->cipher;
696 784
697 c->session = s; 785 c->session = s;
709 c->encrypt = encrypt_RC2_128; 797 c->encrypt = encrypt_RC2_128;
710 c->decrypt = decrypt_RC2_128; 798 c->decrypt = decrypt_RC2_128;
711 799
712 c->clear = clear_RC2_128; 800 c->clear = clear_RC2_128;
713 801
714 mpz_init(cr->private_key); 802 mp_init(&cr->private_key);
715 mpz_init(pubkey); 803 mp_init(&pubkey);
716 mwDHRandKeypair(cr->private_key, pubkey); 804 mwDHRandKeypair(&cr->private_key, &pubkey);
717 mwDHExportKey(pubkey, &cr->public_key); 805 mwDHExportKey(&pubkey, &cr->public_key);
718 mpz_clear(pubkey); 806 mp_clear(&pubkey);
719 807
720 return c; 808 return c;
721 } 809 }
722 810
723 811
778 g_return_val_if_fail(ci != NULL, NULL); 866 g_return_val_if_fail(ci != NULL, NULL);
779 return ci->channel; 867 return ci->channel;
780 } 868 }
781 869
782 870
783 struct mwEncryptItem *mwCipherInstance_newItem(struct mwCipherInstance *ci) {
784 struct mwCipher *cipher;
785
786 g_return_val_if_fail(ci != NULL, NULL);
787 cipher = ci->cipher;
788
789 g_return_val_if_fail(cipher != NULL, NULL);
790 g_return_val_if_fail(cipher->new_item != NULL, NULL);
791
792 return cipher->new_item(ci);
793 }
794
795
796 void mwCipherInstance_offered(struct mwCipherInstance *ci, 871 void mwCipherInstance_offered(struct mwCipherInstance *ci,
797 struct mwEncryptItem *item) { 872 struct mwEncryptItem *item) {
798 struct mwCipher *cipher; 873 struct mwCipher *cipher;
799 874
800 g_return_if_fail(ci != NULL); 875 g_return_if_fail(ci != NULL);