1 #include "lib9.h"
2 #include "kernel.h"
3 #include <isa.h>
4 #include "interp.h"
5 #include "runt.h"
6 #include "cryptmod.h"
7 #include <mp.h>
8 #include <libsec.h>
9 #include "pool.h"
10 #include "raise.h"
11 #include "ipint.h"
12
13 #define MPX(x) checkIPint((void*)(x))
14
15 static Type* TDigestState;
16 static Type* TAESstate;
17 static Type* TDESstate;
18 static Type* TIDEAstate;
19 static Type* TBFstate;
20 static Type* TRC4state;
21
22 static Type* TSKdsa;
23 static Type* TPKdsa;
24 static Type* TPKsigdsa;
25 static Type* TSKeg;
26 static Type* TPKeg;
27 static Type* TPKsigeg;
28 static Type* TSKrsa;
29 static Type* TPKrsa;
30 static Type* TPKsigrsa;
31
32 static uchar DigestStatemap[] = Crypt_DigestState_map;
33 static uchar AESstatemap[] = Crypt_AESstate_map;
34 static uchar DESstatemap[] = Crypt_DESstate_map;
35 static uchar IDEAstatemap[] = Crypt_IDEAstate_map;
36 static uchar BFstatemap[] = Crypt_BFstate_map;
37 static uchar RC4statemap[] = Crypt_RC4state_map;
38
39 static uchar DSAskmap[] = Crypt_SK_DSA_map;
40 static uchar DSApkmap[] = Crypt_PK_DSA_map;
41 static uchar DSAsigmap[] = Crypt_PKsig_DSA_map;
42 static uchar EGskmap[] = Crypt_SK_Elgamal_map;
43 static uchar EGpkmap[] = Crypt_PK_Elgamal_map;
44 static uchar EGsigmap[] = Crypt_PKsig_Elgamal_map;
45 static uchar RSAskmap[] = Crypt_SK_RSA_map;
46 static uchar RSApkmap[] = Crypt_PK_RSA_map;
47 static uchar RSAsigmap[] = Crypt_PKsig_RSA_map;
48
49 static char exBadBsize[] = "data not multiple of block size";
50 static char exBadKey[] = "bad encryption key";
51 static char exBadDigest[] = "bad digest value";
52 static char exBadIvec[] = "bad ivec";
53 static char exBadState[] = "bad encryption state";
54
55 /*
56 * these structures reveal the C state of Limbo adts in crypt.m
57 */
58
59 typedef struct XDigestState XDigestState;
60 typedef struct XAESstate XAESstate;
61 typedef struct XDESstate XDESstate;
62 typedef struct XIDEAstate XIDEAstate;
63 typedef struct XBFstate XBFstate;
64 typedef struct XRC4state XRC4state;
65
66 /* digest state */
67 struct XDigestState
68 {
69 Crypt_DigestState x;
70 DigestState state;
71 };
72
73 /* AES state */
74 struct XAESstate
75 {
76 Crypt_AESstate x;
77 AESstate state;
78 };
79
80 /* DES state */
81 struct XDESstate
82 {
83 Crypt_DESstate x;
84 DESstate state;
85 };
86
87 /* IDEA state */
88 struct XIDEAstate
89 {
90 Crypt_IDEAstate x;
91 IDEAstate state;
92 };
93
94 /* BF state */
95 struct XBFstate
96 {
97 Crypt_BFstate x;
98 BFstate state;
99 };
100
101 /* RC4 state */
102 struct XRC4state
103 {
104 Crypt_RC4state x;
105 RC4state state;
106 };
107
108 static Crypt_PK*
newPK(Type * t,int pick)109 newPK(Type *t, int pick)
110 {
111 Heap *h;
112 Crypt_PK *sk;
113
114 h = heap(t);
115 sk = H2D(Crypt_PK*, h);
116 sk->pick = pick;
117 return sk;
118 }
119
120 static Crypt_SK*
newSK(Crypt_SK ** ret,Type * t,int pick)121 newSK(Crypt_SK** ret, Type *t, int pick)
122 {
123 Heap *h;
124 Crypt_SK *sk;
125
126 h = heap(t);
127 sk = H2D(Crypt_SK*, h);
128 sk->pick = pick;
129 if(ret != nil)
130 *ret = sk;
131 switch(pick){
132 case Crypt_PK_RSA:
133 sk->u.RSA.pk = newPK(TPKrsa, Crypt_PK_RSA);
134 break;
135 case Crypt_PK_Elgamal:
136 sk->u.Elgamal.pk = newPK(TPKeg, Crypt_PK_Elgamal);
137 break;
138 case Crypt_PK_DSA:
139 sk->u.DSA.pk = newPK(TPKdsa, Crypt_PK_DSA);
140 break;
141 default:
142 error(exType);
143 }
144 return sk;
145 }
146
147 static Crypt_PKsig*
newPKsig(Type * t,int pick)148 newPKsig(Type *t, int pick)
149 {
150 Heap *h;
151 Crypt_PKsig *s;
152
153 h = heap(t);
154 s = H2D(Crypt_PKsig*, h);
155 s->pick = pick;
156 return s;
157 }
158
159 static IPints_IPint*
ipcopymp(mpint * b)160 ipcopymp(mpint* b)
161 {
162 if(b == nil)
163 return H;
164 return newIPint(mpcopy(b));
165 }
166
167 /*
168 * digests
169 */
170 void
DigestState_copy(void * fp)171 DigestState_copy(void *fp)
172 {
173 F_DigestState_copy *f;
174 Heap *h;
175 XDigestState *ds, *ods;
176 void *r;
177
178 f = fp;
179 r = *f->ret;
180 *f->ret = H;
181 destroy(r);
182
183 if(f->d != H){
184 ods = checktype(f->d, TDigestState, "DigestState", 0);
185 h = heap(TDigestState);
186 ds = H2D(XDigestState*, h);
187 memmove(&ds->state, &ods->state, sizeof(ds->state));
188 *f->ret = (Crypt_DigestState*)ds;
189 }
190 }
191
192 static Crypt_DigestState*
crypt_digest_x(Array * buf,int n,Array * digest,int dlen,Crypt_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,DigestState *))193 crypt_digest_x(Array *buf, int n, Array *digest, int dlen, Crypt_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, DigestState*))
194 {
195 Heap *h;
196 XDigestState *ds;
197 uchar *cbuf, *cdigest;
198
199 if(buf != H){
200 if(n > buf->len)
201 n = buf->len;
202 cbuf = buf->data;
203 }else{
204 if(n != 0)
205 error(exInval);
206 cbuf = nil;
207 }
208
209 if(digest != H){
210 if(digest->len < dlen)
211 error(exBadDigest);
212 cdigest = digest->data;
213 } else
214 cdigest = nil;
215
216 if(state == H){
217 h = heap(TDigestState);
218 ds = H2D(XDigestState*, h);
219 memset(&ds->state, 0, sizeof(ds->state));
220 } else
221 ds = checktype(state, TDigestState, "DigestState", 1);
222
223 (*fn)(cbuf, n, cdigest, &ds->state);
224
225 return (Crypt_DigestState*)ds;
226 }
227
228 void
Crypt_sha1(void * fp)229 Crypt_sha1(void *fp)
230 {
231 F_Crypt_sha1 *f;
232 void *r;
233
234 f = fp;
235 r = *f->ret;
236 *f->ret = H;
237 destroy(r);
238
239 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA1dlen, f->state, sha1);
240 }
241
242 void
Crypt_sha224(void * fp)243 Crypt_sha224(void *fp)
244 {
245 F_Crypt_sha224 *f;
246 void *r;
247
248 f = fp;
249 r = *f->ret;
250 *f->ret = H;
251 destroy(r);
252
253 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA224dlen, f->state, sha224);
254 }
255
256 void
Crypt_sha256(void * fp)257 Crypt_sha256(void *fp)
258 {
259 F_Crypt_sha256 *f;
260 void *r;
261
262 f = fp;
263 r = *f->ret;
264 *f->ret = H;
265 destroy(r);
266
267 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA256dlen, f->state, sha256);
268 }
269
270 void
Crypt_sha384(void * fp)271 Crypt_sha384(void *fp)
272 {
273 F_Crypt_sha384 *f;
274 void *r;
275
276 f = fp;
277 r = *f->ret;
278 *f->ret = H;
279 destroy(r);
280
281 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA384dlen, f->state, sha384);
282 }
283
284 void
Crypt_sha512(void * fp)285 Crypt_sha512(void *fp)
286 {
287 F_Crypt_sha512 *f;
288 void *r;
289
290 f = fp;
291 r = *f->ret;
292 *f->ret = H;
293 destroy(r);
294
295 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA512dlen, f->state, sha512);
296 }
297
298 void
Crypt_md5(void * fp)299 Crypt_md5(void *fp)
300 {
301 F_Crypt_md5 *f;
302 void *r;
303
304 f = fp;
305 r = *f->ret;
306 *f->ret = H;
307 destroy(r);
308
309 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, MD5dlen, f->state, md5);
310 }
311
312 void
Crypt_md4(void * fp)313 Crypt_md4(void *fp)
314 {
315 F_Crypt_md4 *f;
316 void *r;
317
318 f = fp;
319 r = *f->ret;
320 *f->ret = H;
321 destroy(r);
322
323 *f->ret = crypt_digest_x(f->buf, f->n, f->digest, MD4dlen, f->state, md4);
324 }
325
326 static Crypt_DigestState*
crypt_hmac_x(Array * data,int n,Array * key,Array * digest,int dlen,Crypt_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,ulong,uchar *,DigestState *))327 crypt_hmac_x(Array *data, int n, Array *key, Array *digest, int dlen, Crypt_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*))
328 {
329 Heap *h;
330 XDigestState *ds;
331 uchar *cdata, *cdigest;
332
333 if(data != H){
334 if(n > data->len)
335 n = data->len;
336 cdata = data->data;
337 }else{
338 if(n != 0)
339 error(exInval);
340 cdata = nil;
341 }
342
343 if(key == H || key->len > 64)
344 error(exBadKey);
345
346 if(digest != H){
347 if(digest->len < dlen)
348 error(exBadDigest);
349 cdigest = digest->data;
350 } else
351 cdigest = nil;
352
353 if(state == H){
354 h = heap(TDigestState);
355 ds = H2D(XDigestState*, h);
356 memset(&ds->state, 0, sizeof(ds->state));
357 } else
358 ds = checktype(state, TDigestState, "DigestState", 1);
359
360 (*fn)(cdata, n, key->data, key->len, cdigest, &ds->state);
361
362 return (Crypt_DigestState*)ds;
363 }
364
365 void
Crypt_hmac_sha1(void * fp)366 Crypt_hmac_sha1(void *fp)
367 {
368 F_Crypt_hmac_sha1 *f;
369 void *r;
370
371 f = fp;
372 r = *f->ret;
373 *f->ret = H;
374 destroy(r);
375 *f->ret = crypt_hmac_x(f->data, f->n, f->key, f->digest, SHA1dlen, f->state, hmac_sha1);
376 }
377
378 void
Crypt_hmac_md5(void * fp)379 Crypt_hmac_md5(void *fp)
380 {
381 F_Crypt_hmac_md5 *f;
382 void *r;
383
384 f = fp;
385 r = *f->ret;
386 *f->ret = H;
387 destroy(r);
388 *f->ret = crypt_hmac_x(f->data, f->n, f->key, f->digest, MD5dlen, f->state, hmac_md5);
389 }
390
391 void
Crypt_dhparams(void * fp)392 Crypt_dhparams(void *fp)
393 {
394 F_Crypt_dhparams *f;
395 mpint *p, *alpha;
396 void *v;
397
398 f = fp;
399 v = f->ret->t0;
400 f->ret->t0 = H;
401 destroy(v);
402 v = f->ret->t1;
403 f->ret->t1 = H;
404 destroy(v);
405
406 p = mpnew(0);
407 alpha = mpnew(0);
408 release();
409 if(f->nbits == 1024)
410 DSAprimes(alpha, p, nil);
411 else
412 gensafeprime(p, alpha, f->nbits, 0);
413 acquire();
414 f->ret->t0 = newIPint(alpha);
415 f->ret->t1 = newIPint(p);
416 }
417
418 void
cryptmodinit(void)419 cryptmodinit(void)
420 {
421 ipintsmodinit(); /* TIPint */
422
423 TDigestState = dtype(freeheap, sizeof(XDigestState), DigestStatemap, sizeof(DigestStatemap));
424 TAESstate = dtype(freeheap, sizeof(XAESstate), AESstatemap, sizeof(AESstatemap));
425 TDESstate = dtype(freeheap, sizeof(XDESstate), DESstatemap, sizeof(DESstatemap));
426 TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap, sizeof(IDEAstatemap));
427 TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap, sizeof(BFstatemap));
428 TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap, sizeof(RC4statemap));
429
430 TSKdsa = dtype(freeheap, Crypt_SK_DSA_size, DSAskmap, sizeof(DSAskmap));
431 TPKdsa = dtype(freeheap, Crypt_PK_DSA_size, DSApkmap, sizeof(DSApkmap));
432 TPKsigdsa = dtype(freeheap, Crypt_PKsig_DSA_size, DSAsigmap, sizeof(DSAsigmap));
433 TSKeg = dtype(freeheap, Crypt_SK_Elgamal_size, EGskmap, sizeof(EGskmap));
434 TPKeg = dtype(freeheap, Crypt_PK_Elgamal_size, EGpkmap, sizeof(EGpkmap));
435 TPKsigeg = dtype(freeheap, Crypt_PKsig_Elgamal_size, EGsigmap, sizeof(EGsigmap));
436 TSKrsa = dtype(freeheap, Crypt_SK_RSA_size, RSAskmap, sizeof(RSAskmap));
437 TPKrsa = dtype(freeheap, Crypt_PK_RSA_size, RSApkmap, sizeof(RSApkmap));
438 TPKsigrsa = dtype(freeheap, Crypt_PKsig_RSA_size, RSAsigmap, sizeof(RSAsigmap));
439
440 builtinmod("$Crypt", Cryptmodtab, Cryptmodlen);
441 }
442
443 void
Crypt_dessetup(void * fp)444 Crypt_dessetup(void *fp)
445 {
446 F_Crypt_dessetup *f;
447 Heap *h;
448 XDESstate *ds;
449 uchar *ivec;
450 void *v;
451
452 f = fp;
453 v = *f->ret;
454 *f->ret = H;
455 destroy(v);
456
457 if(f->key == H)
458 error(exNilref);
459 if(f->key->len < 8)
460 error(exBadKey);
461 if(f->ivec != H){
462 if(f->ivec->len < 8)
463 error(exBadIvec);
464 ivec = f->ivec->data;
465 }else
466 ivec = nil;
467
468 h = heap(TDESstate);
469 ds = H2D(XDESstate*, h);
470 setupDESstate(&ds->state, f->key->data, ivec);
471
472 *f->ret = (Crypt_DESstate*)ds;
473 }
474
475 void
Crypt_desecb(void * fp)476 Crypt_desecb(void *fp)
477 {
478 F_Crypt_desecb *f;
479 XDESstate *ds;
480 int i;
481 uchar *p;
482
483 f = fp;
484
485 if(f->buf == H)
486 return;
487 if(f->n < 0 || f->n > f->buf->len)
488 error(exBounds);
489 if(f->n & 7)
490 error(exBadBsize);
491
492 ds = checktype(f->state, TDESstate, exBadState, 0);
493 p = f->buf->data;
494
495 for(i = 8; i <= f->n; i += 8, p += 8)
496 block_cipher(ds->state.expanded, p, f->direction);
497 }
498
499 void
Crypt_descbc(void * fp)500 Crypt_descbc(void *fp)
501 {
502 F_Crypt_descbc *f;
503 XDESstate *ds;
504 uchar *p, *ep, *ip, *p2, *eip;
505 uchar tmp[8];
506
507 f = fp;
508
509 if(f->buf == H)
510 return;
511 if(f->n < 0 || f->n > f->buf->len)
512 error(exBounds);
513 if(f->n & 7)
514 error(exBadBsize);
515
516 ds = checktype(f->state, TDESstate, exBadState, 0);
517 p = f->buf->data;
518
519 if(f->direction == 0){
520 for(ep = p + f->n; p < ep; p += 8){
521 p2 = p;
522 ip = ds->state.ivec;
523 for(eip = ip+8; ip < eip; )
524 *p2++ ^= *ip++;
525 block_cipher(ds->state.expanded, p, 0);
526 memmove(ds->state.ivec, p, 8);
527 }
528 } else {
529 for(ep = p + f->n; p < ep; ){
530 memmove(tmp, p, 8);
531 block_cipher(ds->state.expanded, p, 1);
532 p2 = tmp;
533 ip = ds->state.ivec;
534 for(eip = ip+8; ip < eip; ){
535 *p++ ^= *ip;
536 *ip++ = *p2++;
537 }
538 }
539 }
540 }
541
542 void
Crypt_ideasetup(void * fp)543 Crypt_ideasetup(void *fp)
544 {
545 F_Crypt_ideasetup *f;
546 Heap *h;
547 XIDEAstate *is;
548 uchar *ivec;
549 void *v;
550
551 f = fp;
552 v = *f->ret;
553 *f->ret = H;
554 destroy(v);
555
556 if(f->key == H)
557 error(exNilref);
558 if(f->key->len < 16)
559 error(exBadKey);
560 if(f->ivec != H){
561 if(f->ivec->len < 8)
562 error(exBadIvec);
563 ivec = f->ivec->data;
564 }else
565 ivec = nil;
566
567 h = heap(TIDEAstate);
568 is = H2D(XIDEAstate*, h);
569
570 setupIDEAstate(&is->state, f->key->data, ivec);
571
572 *f->ret = (Crypt_IDEAstate*)is;
573 }
574
575 void
Crypt_ideaecb(void * fp)576 Crypt_ideaecb(void *fp)
577 {
578 F_Crypt_ideaecb *f;
579 XIDEAstate *is;
580 int i;
581 uchar *p;
582
583 f = fp;
584
585 if(f->buf == H)
586 return;
587 if(f->n < 0 || f->n > f->buf->len)
588 error(exBounds);
589 if(f->n & 7)
590 error(exBadBsize);
591
592 is = checktype(f->state, TIDEAstate, exBadState, 0);
593 p = f->buf->data;
594
595 for(i = 8; i <= f->n; i += 8, p += 8)
596 idea_cipher(is->state.edkey, p, f->direction);
597 }
598
599 void
Crypt_ideacbc(void * fp)600 Crypt_ideacbc(void *fp)
601 {
602 F_Crypt_ideacbc *f;
603 XIDEAstate *is;
604 uchar *p, *ep, *ip, *p2, *eip;
605 uchar tmp[8];
606
607 f = fp;
608
609 if(f->buf == H)
610 return;
611 if(f->n < 0 || f->n > f->buf->len)
612 error(exBounds);
613 if(f->n & 7)
614 error(exBadBsize);
615
616 is = checktype(f->state, TIDEAstate, exBadState, 0);
617 p = f->buf->data;
618
619 if(f->direction == 0){
620 for(ep = p + f->n; p < ep; p += 8){
621 p2 = p;
622 ip = is->state.ivec;
623 for(eip = ip+8; ip < eip; )
624 *p2++ ^= *ip++;
625 idea_cipher(is->state.edkey, p, 0);
626 memmove(is->state.ivec, p, 8);
627 }
628 } else {
629 for(ep = p + f->n; p < ep; ){
630 memmove(tmp, p, 8);
631 idea_cipher(is->state.edkey, p, 1);
632 p2 = tmp;
633 ip = is->state.ivec;
634 for(eip = ip+8; ip < eip; ){
635 *p++ ^= *ip;
636 *ip++ = *p2++;
637 }
638 }
639 }
640 }
641
642 void
Crypt_aessetup(void * fp)643 Crypt_aessetup(void *fp)
644 {
645 F_Crypt_aessetup *f;
646 Heap *h;
647 XAESstate *is;
648 uchar *ivec;
649 void *v;
650
651 f = fp;
652 v = *f->ret;
653 *f->ret = H;
654 destroy(v);
655
656 if(f->key == H)
657 error(exNilref);
658 if(f->key->len != 16 && f->key->len != 24 && f->key->len != 32)
659 error(exBadKey);
660 if(f->ivec != H){
661 if(f->ivec->len < AESbsize)
662 error(exBadIvec);
663 ivec = f->ivec->data;
664 }else
665 ivec = nil;
666
667 h = heap(TAESstate);
668 is = H2D(XAESstate*, h);
669
670 setupAESstate(&is->state, f->key->data, f->key->len, ivec);
671
672 *f->ret = (Crypt_AESstate*)is;
673 }
674
675 void
Crypt_aescbc(void * fp)676 Crypt_aescbc(void *fp)
677 {
678 F_Crypt_aescbc *f;
679 XAESstate *is;
680 uchar *p;
681
682 f = fp;
683
684 if(f->buf == H)
685 return;
686 if(f->n < 0 || f->n > f->buf->len)
687 error(exBounds);
688
689 is = checktype(f->state, TAESstate, exBadState, 0);
690 p = f->buf->data;
691
692 if(f->direction == 0)
693 aesCBCencrypt(p, f->n, &is->state);
694 else
695 aesCBCdecrypt(p, f->n, &is->state);
696 }
697
698 void
Crypt_blowfishsetup(void * fp)699 Crypt_blowfishsetup(void *fp)
700 {
701 F_Crypt_blowfishsetup *f;
702 Heap *h;
703 XBFstate *is;
704 uchar *ivec;
705 void *v;
706
707 f = fp;
708 v = *f->ret;
709 *f->ret = H;
710 destroy(v);
711
712 if(f->key == H)
713 error(exNilref);
714 if(f->key->len <= 0)
715 error(exBadKey);
716 if(f->ivec != H){
717 if(f->ivec->len != BFbsize)
718 error(exBadIvec);
719 ivec = f->ivec->data;
720 }else
721 ivec = nil;
722
723 h = heap(TBFstate);
724 is = H2D(XBFstate*, h);
725
726 setupBFstate(&is->state, f->key->data, f->key->len, ivec);
727
728 *f->ret = (Crypt_BFstate*)is;
729 }
730
731 void
Crypt_blowfishcbc(void * fp)732 Crypt_blowfishcbc(void *fp)
733 {
734 F_Crypt_blowfishcbc *f;
735 XBFstate *is;
736 uchar *p;
737
738 f = fp;
739
740 if(f->state == H)
741 return;
742 if(f->n < 0 || f->n > f->buf->len)
743 error(exBounds);
744 if(f->n & 7)
745 error(exBadBsize);
746
747 is = checktype(f->state, TBFstate, exBadState, 0);
748 p = f->buf->data;
749
750 if(f->direction == 0)
751 bfCBCencrypt(p, f->n, &is->state);
752 else
753 bfCBCdecrypt(p, f->n, &is->state);
754 }
755
756 void
Crypt_rc4setup(void * fp)757 Crypt_rc4setup(void *fp)
758 {
759 F_Crypt_rc4setup *f;
760 Heap *h;
761 XRC4state *is;
762 void *v;
763
764 f = fp;
765 v = *f->ret;
766 *f->ret = H;
767 destroy(v);
768
769 if(f->seed == H)
770 error(exNilref);
771
772 h = heap(TRC4state);
773 is = H2D(XRC4state*, h);
774
775 setupRC4state(&is->state, f->seed->data, f->seed->len);
776
777 *f->ret = (Crypt_RC4state*)is;
778 }
779
780 void
Crypt_rc4(void * fp)781 Crypt_rc4(void *fp)
782 {
783 F_Crypt_rc4 *f;
784 XRC4state *is;
785 uchar *p;
786
787 f = fp;
788 if(f->buf == H)
789 return;
790 if(f->n < 0 || f->n > f->buf->len)
791 error(exBounds);
792 is = checktype(f->state, TRC4state, exBadState, 0);
793 p = f->buf->data;
794 rc4(&is->state, p, f->n);
795 }
796
797 void
Crypt_rc4skip(void * fp)798 Crypt_rc4skip(void *fp)
799 {
800 F_Crypt_rc4skip *f;
801 XRC4state *is;
802
803 f = fp;
804 is = checktype(f->state, TRC4state, exBadState, 0);
805 rc4skip(&is->state, f->n);
806 }
807
808 void
Crypt_rc4back(void * fp)809 Crypt_rc4back(void *fp)
810 {
811 F_Crypt_rc4back *f;
812 XRC4state *is;
813
814 f = fp;
815 is = checktype(f->state, TRC4state, exBadState, 0);
816 rc4back(&is->state, f->n);
817 }
818
819 /*
820 * public/secret keys, signing and verifying
821 */
822
823 /*
824 * DSA
825 */
826
827 static void
dsapk2pub(DSApub * p,Crypt_PK * pk)828 dsapk2pub(DSApub* p, Crypt_PK* pk)
829 {
830 if(pk == H)
831 error(exNilref);
832 if(pk->pick != Crypt_PK_DSA)
833 error(exType);
834 p->p = MPX(pk->u.DSA.p);
835 p->q = MPX(pk->u.DSA.q);
836 p->alpha = MPX(pk->u.DSA.alpha);
837 p->key = MPX(pk->u.DSA.key);
838 }
839
840 static void
dsask2priv(DSApriv * p,Crypt_SK * sk)841 dsask2priv(DSApriv* p, Crypt_SK* sk)
842 {
843 if(sk == H)
844 error(exNilref);
845 if(sk->pick != Crypt_SK_DSA)
846 error(exType);
847 dsapk2pub(&p->pub, sk->u.DSA.pk);
848 p->secret = MPX(sk->u.DSA.secret);
849 }
850
851 static void
dsapriv2sk(Crypt_SK * sk,DSApriv * p)852 dsapriv2sk(Crypt_SK* sk, DSApriv* p)
853 {
854 Crypt_PK *pk;
855
856 pk = sk->u.DSA.pk;
857 pk->u.DSA.p = ipcopymp(p->pub.p);
858 pk->u.DSA.q = ipcopymp(p->pub.q);
859 pk->u.DSA.alpha = ipcopymp(p->pub.alpha);
860 pk->u.DSA.key = ipcopymp(p->pub.key);
861 sk->u.DSA.secret = ipcopymp(p->secret);
862 }
863
864 static void
dsaxgen(Crypt_SK * sk,DSApub * oldpk)865 dsaxgen(Crypt_SK* sk, DSApub* oldpk)
866 {
867 DSApriv *p;
868
869 release();
870 p = dsagen(oldpk);
871 acquire();
872 dsapriv2sk(sk, p);
873 dsaprivfree(p);
874 }
875
876 void
Crypt_dsagen(void * fp)877 Crypt_dsagen(void *fp)
878 {
879 F_Crypt_dsagen *f;
880 Crypt_SK *sk;
881 DSApub pub, *oldpk;
882 void *v;
883
884 f = fp;
885 v = *f->ret;
886 *f->ret = H;
887 destroy(v);
888
889 sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
890 oldpk = nil;
891 if(f->oldpk != H && f->oldpk->pick == Crypt_PK_DSA){
892 dsapk2pub(&pub, f->oldpk);
893 oldpk = &pub;
894 }
895 dsaxgen(sk, oldpk);
896 }
897
898 /*
899 * Elgamal
900 */
901
902 static void
egpk2pub(EGpub * p,Crypt_PK * pk)903 egpk2pub(EGpub* p, Crypt_PK* pk)
904 {
905 if(pk == H)
906 error(exNilref);
907 if(pk->pick != Crypt_PK_Elgamal)
908 error(exType);
909 p->p = MPX(pk->u.Elgamal.p);
910 p->alpha = MPX(pk->u.Elgamal.alpha);
911 p->key = MPX(pk->u.Elgamal.key);
912 }
913
914 static void
egsk2priv(EGpriv * p,Crypt_SK * sk)915 egsk2priv(EGpriv* p, Crypt_SK* sk)
916 {
917 if(sk == H)
918 error(exNilref);
919 if(sk->pick != Crypt_SK_Elgamal)
920 error(exType);
921 egpk2pub(&p->pub, sk->u.Elgamal.pk);
922 p->secret = MPX(sk->u.Elgamal.secret);
923 }
924
925 static void
egpriv2sk(Crypt_SK * sk,EGpriv * p)926 egpriv2sk(Crypt_SK* sk, EGpriv* p)
927 {
928 Crypt_PK* pk;
929
930 pk = sk->u.Elgamal.pk;
931 pk->u.Elgamal.p = ipcopymp(p->pub.p);
932 pk->u.Elgamal.alpha = ipcopymp(p->pub.alpha);
933 pk->u.Elgamal.key = ipcopymp(p->pub.key);
934 sk->u.Elgamal.secret = ipcopymp(p->secret);
935 }
936
937 static void
egxgen(Crypt_SK * sk,int nlen,int nrep)938 egxgen(Crypt_SK* sk, int nlen, int nrep)
939 {
940 EGpriv *p;
941
942 release();
943 for(;;){
944 p = eggen(nlen, nrep);
945 if(mpsignif(p->pub.p) == nlen)
946 break;
947 egprivfree(p);
948 }
949 acquire();
950 egpriv2sk(sk, p);
951 egprivfree(p);
952 }
953
954
955 void
Crypt_eggen(void * fp)956 Crypt_eggen(void *fp)
957 {
958 F_Crypt_eggen *f;
959 Crypt_SK *sk;
960 void *v;
961
962 f = fp;
963 v = *f->ret;
964 *f->ret = H;
965 destroy(v);
966
967 sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
968 egxgen(sk, f->nlen, f->nrep);
969 }
970
971 /*
972 * RSA
973 */
974
975 static void
rsapk2pub(RSApub * p,Crypt_PK * pk)976 rsapk2pub(RSApub* p, Crypt_PK* pk)
977 {
978 if(pk == H)
979 error(exNilref);
980 if(pk->pick != Crypt_PK_RSA)
981 error(exType);
982 p->n = MPX(pk->u.RSA.n);
983 p->ek = MPX(pk->u.RSA.ek);
984 }
985
986 static void
rsask2priv(RSApriv * p,Crypt_SK * sk)987 rsask2priv(RSApriv* p, Crypt_SK* sk)
988 {
989 if(sk == H)
990 error(exNilref);
991 if(sk->pick != Crypt_SK_RSA)
992 error(exType);
993 rsapk2pub(&p->pub, sk->u.RSA.pk);
994 p->dk = MPX(sk->u.RSA.dk);
995 p->p = MPX(sk->u.RSA.p);
996 p->q = MPX(sk->u.RSA.q);
997 p->kp = MPX(sk->u.RSA.kp);
998 p->kq = MPX(sk->u.RSA.kq);
999 p->c2 = MPX(sk->u.RSA.c2);
1000 }
1001
1002 static void
rsapriv2sk(Crypt_SK * sk,RSApriv * p)1003 rsapriv2sk(Crypt_SK* sk, RSApriv* p)
1004 {
1005 Crypt_PK *pk;
1006
1007 pk = sk->u.RSA.pk;
1008 pk->u.RSA.n = ipcopymp(p->pub.n);
1009 pk->u.RSA.ek = ipcopymp(p->pub.ek);
1010 sk->u.RSA.dk = ipcopymp(p->dk);
1011 sk->u.RSA.p = ipcopymp(p->p);
1012 sk->u.RSA.q = ipcopymp(p->q);
1013 sk->u.RSA.kp = ipcopymp(p->kp);
1014 sk->u.RSA.kq = ipcopymp(p->kq);
1015 sk->u.RSA.c2 = ipcopymp(p->c2);
1016 }
1017
1018 static void
rsaxgen(Crypt_SK * sk,int nlen,int elen,int nrep)1019 rsaxgen(Crypt_SK *sk, int nlen, int elen, int nrep)
1020 {
1021 RSApriv *p;
1022
1023 release();
1024 for(;;){
1025 p = rsagen(nlen, elen, nrep);
1026 if(mpsignif(p->pub.n) == nlen)
1027 break;
1028 rsaprivfree(p);
1029 }
1030 acquire();
1031 rsapriv2sk(sk, p);
1032 rsaprivfree(p);
1033 }
1034
1035 void
Crypt_rsagen(void * fp)1036 Crypt_rsagen(void *fp)
1037 {
1038 F_Crypt_rsagen *f;
1039 Crypt_SK *sk;
1040 void *v;
1041
1042 f = fp;
1043 v = *f->ret;
1044 *f->ret = H;
1045 destroy(v);
1046
1047 sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1048 rsaxgen(sk, f->nlen, f->elen, f->nrep);
1049 }
1050
1051 void
Crypt_rsafill(void * fp)1052 Crypt_rsafill(void *fp)
1053 {
1054 F_Crypt_rsafill *f;
1055 Crypt_SK *sk;
1056 RSApriv *p;
1057 void *v;
1058
1059 f = fp;
1060 v = *f->ret;
1061 *f->ret = H;
1062 destroy(v);
1063
1064 sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1065 release();
1066 p = rsafill(MPX(f->n), MPX(f->ek), MPX(f->dk),
1067 MPX(f->p), MPX(f->q));
1068 acquire();
1069 if(p == nil) {
1070 *f->ret = H;
1071 destroy(sk);
1072 }else{
1073 rsapriv2sk(sk, p);
1074 rsaprivfree(p);
1075 }
1076 }
1077
1078 void
Crypt_rsaencrypt(void * fp)1079 Crypt_rsaencrypt(void *fp)
1080 {
1081 F_Crypt_rsaencrypt *f;
1082 RSApub p;
1083 mpint *m, *o;
1084 void *v;
1085
1086 f = fp;
1087 v = *f->ret;
1088 *f->ret = H;
1089 destroy(v);
1090
1091 rsapk2pub(&p, f->k);
1092 m = MPX(f->m);
1093 release();
1094 o = rsaencrypt(&p, m, nil);
1095 acquire();
1096 *f->ret = newIPint(o);
1097 }
1098
1099 void
Crypt_rsadecrypt(void * fp)1100 Crypt_rsadecrypt(void *fp)
1101 {
1102 F_Crypt_rsadecrypt *f;
1103 RSApriv p;
1104 mpint *m, *o;
1105 void *v;
1106
1107 f = fp;
1108 v = *f->ret;
1109 *f->ret = H;
1110 destroy(v);
1111
1112 rsask2priv(&p, f->k);
1113 m = MPX(f->m);
1114 release();
1115 o = rsadecrypt(&p, m, nil);
1116 acquire();
1117 *f->ret = newIPint(o);
1118 }
1119
1120 /*
1121 * generic key functions
1122 */
1123
1124 void
Crypt_genSK(void * fp)1125 Crypt_genSK(void *fp)
1126 {
1127 F_Crypt_genSK *f;
1128 Crypt_SK *sk;
1129 char *sa;
1130 void *v;
1131
1132 f = fp;
1133 v = *f->ret;
1134 *f->ret = H;
1135 destroy(v);
1136
1137 sa = string2c(f->algname);
1138 if(strcmp(sa, "rsa") == 0){
1139 sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1140 rsaxgen(sk, f->length, 6, 0);
1141 }else if(strcmp(sa, "dsa") == 0){
1142 sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
1143 dsaxgen(sk, nil);
1144 }else if(strcmp(sa, "elgamal") == 0){
1145 sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
1146 egxgen(sk, f->length, 0);
1147 }
1148 /* genSK returns nil for unknown algorithm */
1149 }
1150
1151 void
Crypt_genSKfromPK(void * fp)1152 Crypt_genSKfromPK(void *fp)
1153 {
1154 F_Crypt_genSKfromPK *f;
1155 Crypt_SK *sk;
1156 void *v;
1157
1158 f = fp;
1159 v = *f->ret;
1160 *f->ret = H;
1161 destroy(v);
1162
1163 if(f->pk == H)
1164 error(exNilref);
1165 switch(f->pk->pick){
1166 case Crypt_PK_RSA: {
1167 RSApub p;
1168
1169 rsapk2pub(&p, f->pk);
1170 sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1171 rsaxgen(sk, mpsignif(p.n), mpsignif(p.ek), 0);
1172 }
1173 break;
1174 case Crypt_PK_Elgamal: {
1175 EGpub p;
1176
1177 egpk2pub(&p, f->pk);
1178 sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
1179 egxgen(sk, mpsignif(p.p), 0);
1180 }
1181 break;
1182 case Crypt_PK_DSA: {
1183 DSApub p;
1184
1185 dsapk2pub(&p, f->pk);
1186 sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
1187 dsaxgen(sk, &p);
1188 }
1189 break;
1190 default:
1191 /* shouldn't happen */
1192 error(exType);
1193 }
1194 }
1195
1196 void
Crypt_sktopk(void * fp)1197 Crypt_sktopk(void *fp)
1198 {
1199 F_Crypt_sktopk *f;
1200 Crypt_PK *pk;
1201 void *v;
1202
1203 f = fp;
1204 v = *f->ret;
1205 *f->ret = H;
1206 destroy(v);
1207 if(f->sk == H)
1208 error(exNilref);
1209 switch(f->sk->pick){
1210 case Crypt_PK_RSA:
1211 pk = f->sk->u.RSA.pk;
1212 break;
1213 case Crypt_PK_Elgamal:
1214 pk = f->sk->u.Elgamal.pk;
1215 break;
1216 case Crypt_PK_DSA:
1217 pk = f->sk->u.DSA.pk;
1218 break;
1219 default:
1220 pk = H;
1221 error(exType);
1222 }
1223 if(pk == H)
1224 return;
1225 D2H(pk)->ref++;
1226 *f->ret = pk;
1227 }
1228
1229 void
Crypt_sign(void * fp)1230 Crypt_sign(void *fp)
1231 {
1232 F_Crypt_sign *f;
1233 Crypt_PKsig *sig;
1234 mpint *m;
1235 void *v;
1236
1237 f = fp;
1238 v = *f->ret;
1239 *f->ret = H;
1240 destroy(v);
1241
1242 if(f->m == H || f->sk == H)
1243 error(exNilref);
1244 m = MPX(f->m);
1245 switch(f->sk->pick){
1246 case Crypt_SK_RSA: {
1247 RSApriv p;
1248 mpint *s;
1249
1250 rsask2priv(&p, f->sk);
1251 release();
1252 s = rsadecrypt(&p, m, nil);
1253 acquire();
1254 sig = newPKsig(TPKsigrsa, Crypt_PKsig_RSA);
1255 sig->u.RSA.n = newIPint(s);
1256 }
1257 break;
1258 case Crypt_SK_Elgamal: {
1259 EGpriv p;
1260 EGsig *s;
1261
1262 egsk2priv(&p, f->sk);
1263 release();
1264 s = egsign(&p, m);
1265 acquire();
1266 sig = newPKsig(TPKsigeg, Crypt_PKsig_Elgamal);
1267 sig->u.Elgamal.r = ipcopymp(s->r);
1268 sig->u.Elgamal.s = ipcopymp(s->s);
1269 egsigfree(s);
1270 }
1271 break;
1272 case Crypt_SK_DSA: {
1273 DSApriv p;
1274 DSAsig *s;
1275
1276 dsask2priv(&p, f->sk);
1277 m = MPX(f->m);
1278 release();
1279 s = dsasign(&p, m);
1280 acquire();
1281 sig = newPKsig(TPKsigdsa, Crypt_PKsig_DSA);
1282 sig->u.DSA.r = ipcopymp(s->r);
1283 sig->u.DSA.s = ipcopymp(s->s);
1284 dsasigfree(s);
1285 }
1286 break;
1287 default:
1288 sig = H;
1289 error(exType);
1290 }
1291 *f->ret = sig;
1292 }
1293
1294 void
Crypt_verify(void * fp)1295 Crypt_verify(void *fp)
1296 {
1297 F_Crypt_verify *f;
1298 mpint *m;
1299
1300 f = fp;
1301 *f->ret = 0;
1302 if(f->sig == H || f->pk == H)
1303 error(exNilref);
1304 if(f->sig->pick != f->pk->pick)
1305 return; /* key type and signature mismatch, doesn't validate */
1306 m = MPX(f->m);
1307 switch(f->pk->pick){
1308 case Crypt_PK_RSA: {
1309 RSApub p;
1310 mpint *sig, *t;
1311
1312 rsapk2pub(&p, f->pk);
1313 sig = MPX(f->sig->u.RSA.n);
1314 release();
1315 t = rsaencrypt(&p, sig, nil);
1316 *f->ret = mpcmp(t, m) == 0;
1317 mpfree(t);
1318 acquire();
1319 }
1320 break;
1321 case Crypt_PK_Elgamal: {
1322 EGpub p;
1323 EGsig sig;
1324
1325 egpk2pub(&p, f->pk);
1326 sig.r = MPX(f->sig->u.Elgamal.r);
1327 sig.s = MPX(f->sig->u.Elgamal.s);
1328 release();
1329 *f->ret = egverify(&p, &sig, m) == 0;
1330 acquire();
1331 }
1332 break;
1333 case Crypt_PK_DSA: {
1334 DSApub p;
1335 DSAsig sig;
1336
1337 dsapk2pub(&p, f->pk);
1338 sig.r = MPX(f->sig->u.DSA.r);
1339 sig.s = MPX(f->sig->u.DSA.s);
1340 release();
1341 *f->ret = dsaverify(&p, &sig, m) == 0;
1342 acquire();
1343 }
1344 break;
1345 default:
1346 error(exType);
1347 }
1348 }
1349