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