xref: /inferno-os/libinterp/crypt.c (revision 06155dbb53eb0585800b239acd6e45b946c6e0cf)
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*
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*
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*
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*
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
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*
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
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
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
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
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
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
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
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*
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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