xref: /inferno-os/libkeyring/egalg.c (revision 7de2b42d50e3c05cc143e7b51284009b5e185581)
137da2899SCharles.Forsyth #include <lib9.h>
237da2899SCharles.Forsyth #include <kernel.h>
337da2899SCharles.Forsyth #include <isa.h>
437da2899SCharles.Forsyth #include "interp.h"
5*7de2b42dSforsyth #include "../libinterp/keyringif.h"
637da2899SCharles.Forsyth #include "mp.h"
737da2899SCharles.Forsyth #include "libsec.h"
837da2899SCharles.Forsyth #include "keys.h"
937da2899SCharles.Forsyth 
1037da2899SCharles.Forsyth static char*	pkattr[] = { "p", "alpha", "key", nil };
1137da2899SCharles.Forsyth static char*	skattr[] = { "p", "alpha", "key", "!secret", nil };
1237da2899SCharles.Forsyth static char*	sigattr[] = { "r", "s", nil };
1337da2899SCharles.Forsyth 
1437da2899SCharles.Forsyth static void*
eg_str2sk(char * str,char ** strp)1537da2899SCharles.Forsyth eg_str2sk(char *str, char **strp)
1637da2899SCharles.Forsyth {
1737da2899SCharles.Forsyth 	EGpriv *eg;
1837da2899SCharles.Forsyth 	char *p;
1937da2899SCharles.Forsyth 
2037da2899SCharles.Forsyth 	eg = egprivalloc();
2137da2899SCharles.Forsyth 	eg->pub.p = base64tobig(str, &p);
2237da2899SCharles.Forsyth 	eg->pub.alpha = base64tobig(p, &p);
2337da2899SCharles.Forsyth 	eg->pub.key = base64tobig(p, &p);
2437da2899SCharles.Forsyth 	eg->secret = base64tobig(p, &p);
2537da2899SCharles.Forsyth 	if(strp)
2637da2899SCharles.Forsyth 		*strp = p;
27032c0afdSforsyth 	if(eg->pub.p == nil || eg->pub.alpha == nil || eg->pub.key == nil || eg->secret == nil){
28032c0afdSforsyth 		egprivfree(eg);
29032c0afdSforsyth 		return nil;
30032c0afdSforsyth 	}
3137da2899SCharles.Forsyth 	return eg;
3237da2899SCharles.Forsyth }
3337da2899SCharles.Forsyth 
3437da2899SCharles.Forsyth static void*
eg_str2pk(char * str,char ** strp)3537da2899SCharles.Forsyth eg_str2pk(char *str, char **strp)
3637da2899SCharles.Forsyth {
3737da2899SCharles.Forsyth 	EGpub *eg;
3837da2899SCharles.Forsyth 	char *p;
3937da2899SCharles.Forsyth 
4037da2899SCharles.Forsyth 	eg = egpuballoc();
4137da2899SCharles.Forsyth 	eg->p = base64tobig(str, &p);
4237da2899SCharles.Forsyth 	eg->alpha = base64tobig(p, &p);
4337da2899SCharles.Forsyth 	eg->key = base64tobig(p, &p);
4437da2899SCharles.Forsyth 	if(strp)
4537da2899SCharles.Forsyth 		*strp = p;
46032c0afdSforsyth 	if(eg->p == nil || eg->alpha == nil || eg->key == nil){
47032c0afdSforsyth 		egpubfree(eg);
48032c0afdSforsyth 		return nil;
49032c0afdSforsyth 	}
5037da2899SCharles.Forsyth 	return eg;
5137da2899SCharles.Forsyth }
5237da2899SCharles.Forsyth 
5337da2899SCharles.Forsyth static void*
eg_str2sig(char * str,char ** strp)5437da2899SCharles.Forsyth eg_str2sig(char *str, char **strp)
5537da2899SCharles.Forsyth {
5637da2899SCharles.Forsyth 	EGsig *eg;
5737da2899SCharles.Forsyth 	char *p;
5837da2899SCharles.Forsyth 
5937da2899SCharles.Forsyth 	eg = egsigalloc();
6037da2899SCharles.Forsyth 	eg->r = base64tobig(str, &p);
6137da2899SCharles.Forsyth 	eg->s = base64tobig(p, &p);
6237da2899SCharles.Forsyth 	if(strp)
6337da2899SCharles.Forsyth 		*strp = p;
64032c0afdSforsyth 	if(eg->r == nil || eg->s == nil){
65032c0afdSforsyth 		egsigfree(eg);
66032c0afdSforsyth 		return nil;
67032c0afdSforsyth 	}
6837da2899SCharles.Forsyth 	return eg;
6937da2899SCharles.Forsyth }
7037da2899SCharles.Forsyth 
7137da2899SCharles.Forsyth static int
eg_sk2str(void * veg,char * buf,int len)7237da2899SCharles.Forsyth eg_sk2str(void *veg, char *buf, int len)
7337da2899SCharles.Forsyth {
7437da2899SCharles.Forsyth 	EGpriv *eg;
7537da2899SCharles.Forsyth 	char *cp, *ep;
7637da2899SCharles.Forsyth 
7737da2899SCharles.Forsyth 	eg = (EGpriv*)veg;
7837da2899SCharles.Forsyth 	ep = buf + len - 1;
7937da2899SCharles.Forsyth 	cp = buf;
8037da2899SCharles.Forsyth 
8137da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->pub.p);
8237da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->pub.alpha);
8337da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->pub.key);
8437da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->secret);
8537da2899SCharles.Forsyth 	*cp = 0;
8637da2899SCharles.Forsyth 
8737da2899SCharles.Forsyth 	return cp - buf;
8837da2899SCharles.Forsyth }
8937da2899SCharles.Forsyth 
9037da2899SCharles.Forsyth static int
eg_pk2str(void * veg,char * buf,int len)9137da2899SCharles.Forsyth eg_pk2str(void *veg, char *buf, int len)
9237da2899SCharles.Forsyth {
9337da2899SCharles.Forsyth 	EGpub *eg;
9437da2899SCharles.Forsyth 	char *cp, *ep;
9537da2899SCharles.Forsyth 
9637da2899SCharles.Forsyth 	eg = (EGpub*)veg;
9737da2899SCharles.Forsyth 	ep = buf + len - 1;
9837da2899SCharles.Forsyth 	cp = buf;
9937da2899SCharles.Forsyth 
10037da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->p);
10137da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->alpha);
10237da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->key);
10337da2899SCharles.Forsyth 	*cp = 0;
10437da2899SCharles.Forsyth 
10537da2899SCharles.Forsyth 	return cp - buf;
10637da2899SCharles.Forsyth }
10737da2899SCharles.Forsyth 
10837da2899SCharles.Forsyth static int
eg_sig2str(void * veg,char * buf,int len)10937da2899SCharles.Forsyth eg_sig2str(void *veg, char *buf, int len)
11037da2899SCharles.Forsyth {
11137da2899SCharles.Forsyth 	EGsig *eg;
11237da2899SCharles.Forsyth 	char *cp, *ep;
11337da2899SCharles.Forsyth 
11437da2899SCharles.Forsyth 	eg = veg;
11537da2899SCharles.Forsyth 	ep = buf + len - 1;
11637da2899SCharles.Forsyth 	cp = buf;
11737da2899SCharles.Forsyth 
11837da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->r);
11937da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", eg->s);
12037da2899SCharles.Forsyth 	*cp = 0;
12137da2899SCharles.Forsyth 
12237da2899SCharles.Forsyth 	return cp - buf;
12337da2899SCharles.Forsyth }
12437da2899SCharles.Forsyth 
12537da2899SCharles.Forsyth static void*
eg_sk2pk(void * vs)12637da2899SCharles.Forsyth eg_sk2pk(void *vs)
12737da2899SCharles.Forsyth {
12837da2899SCharles.Forsyth 	return egprivtopub((EGpriv*)vs);
12937da2899SCharles.Forsyth }
13037da2899SCharles.Forsyth 
13137da2899SCharles.Forsyth /* generate an el gamal secret key with new params */
13237da2899SCharles.Forsyth static void*
eg_gen(int len)13337da2899SCharles.Forsyth eg_gen(int len)
13437da2899SCharles.Forsyth {
13537da2899SCharles.Forsyth 	return eggen(len, 0);
13637da2899SCharles.Forsyth }
13737da2899SCharles.Forsyth 
13837da2899SCharles.Forsyth /* generate an el gamal secret key with same params as a public key */
13937da2899SCharles.Forsyth static void*
eg_genfrompk(void * vpub)14037da2899SCharles.Forsyth eg_genfrompk(void *vpub)
14137da2899SCharles.Forsyth {
14237da2899SCharles.Forsyth 	EGpub *pub;
14337da2899SCharles.Forsyth 	EGpriv *priv;
14437da2899SCharles.Forsyth 	int nlen;
14537da2899SCharles.Forsyth 
14637da2899SCharles.Forsyth 	pub = vpub;
14737da2899SCharles.Forsyth 	priv = egprivalloc();
14837da2899SCharles.Forsyth 	priv->pub.p = mpcopy(pub->p);
14937da2899SCharles.Forsyth 	priv->pub.alpha = mpcopy(pub->alpha);
15037da2899SCharles.Forsyth 	nlen = mpsignif(pub->p);
15137da2899SCharles.Forsyth 	pub = &priv->pub;
15237da2899SCharles.Forsyth 	pub->key = mpnew(0);
15337da2899SCharles.Forsyth 	priv->secret = mpnew(0);
15437da2899SCharles.Forsyth 	mprand(nlen-1, genrandom, priv->secret);
15537da2899SCharles.Forsyth 	mpexp(pub->alpha, priv->secret, pub->p, pub->key);
15637da2899SCharles.Forsyth 	return priv;
15737da2899SCharles.Forsyth }
15837da2899SCharles.Forsyth 
15937da2899SCharles.Forsyth static void*
eg_sign(mpint * mp,void * key)16031a18a69SCharles.Forsyth eg_sign(mpint* mp, void *key)
16137da2899SCharles.Forsyth {
16237da2899SCharles.Forsyth 	return egsign((EGpriv*)key, mp);
16337da2899SCharles.Forsyth }
16437da2899SCharles.Forsyth 
16537da2899SCharles.Forsyth static int
eg_verify(mpint * mp,void * sig,void * key)16631a18a69SCharles.Forsyth eg_verify(mpint* mp, void *sig, void *key)
16737da2899SCharles.Forsyth {
16837da2899SCharles.Forsyth 	return egverify((EGpub*)key, (EGsig*)sig, mp) == 0;
16937da2899SCharles.Forsyth }
17037da2899SCharles.Forsyth 
17137da2899SCharles.Forsyth static void
eg_freepub(void * a)17237da2899SCharles.Forsyth eg_freepub(void *a)
17337da2899SCharles.Forsyth {
17437da2899SCharles.Forsyth 	egpubfree((EGpub*)a);
17537da2899SCharles.Forsyth }
17637da2899SCharles.Forsyth 
17737da2899SCharles.Forsyth static void
eg_freepriv(void * a)17837da2899SCharles.Forsyth eg_freepriv(void *a)
17937da2899SCharles.Forsyth {
18037da2899SCharles.Forsyth 	egprivfree((EGpriv*)a);
18137da2899SCharles.Forsyth }
18237da2899SCharles.Forsyth 
18337da2899SCharles.Forsyth static void
eg_freesig(void * a)18437da2899SCharles.Forsyth eg_freesig(void *a)
18537da2899SCharles.Forsyth {
18637da2899SCharles.Forsyth 	egsigfree((EGsig*)a);
18737da2899SCharles.Forsyth }
18837da2899SCharles.Forsyth 
18937da2899SCharles.Forsyth SigAlgVec*
elgamalinit(void)19037da2899SCharles.Forsyth elgamalinit(void)
19137da2899SCharles.Forsyth {
19237da2899SCharles.Forsyth 	SigAlgVec *vec;
19337da2899SCharles.Forsyth 
19437da2899SCharles.Forsyth 	vec = malloc(sizeof(SigAlgVec));
19537da2899SCharles.Forsyth 	if(vec == nil)
19637da2899SCharles.Forsyth 		return nil;
19737da2899SCharles.Forsyth 
19837da2899SCharles.Forsyth 	vec->name = "elgamal";
19937da2899SCharles.Forsyth 
20037da2899SCharles.Forsyth 	vec->pkattr = pkattr;
20137da2899SCharles.Forsyth 	vec->skattr = skattr;
20237da2899SCharles.Forsyth 	vec->sigattr = sigattr;
20337da2899SCharles.Forsyth 
20437da2899SCharles.Forsyth 	vec->str2sk = eg_str2sk;
20537da2899SCharles.Forsyth 	vec->str2pk = eg_str2pk;
20637da2899SCharles.Forsyth 	vec->str2sig = eg_str2sig;
20737da2899SCharles.Forsyth 
20837da2899SCharles.Forsyth 	vec->sk2str = eg_sk2str;
20937da2899SCharles.Forsyth 	vec->pk2str = eg_pk2str;
21037da2899SCharles.Forsyth 	vec->sig2str = eg_sig2str;
21137da2899SCharles.Forsyth 
21237da2899SCharles.Forsyth 	vec->sk2pk = eg_sk2pk;
21337da2899SCharles.Forsyth 
21437da2899SCharles.Forsyth 	vec->gensk = eg_gen;
21537da2899SCharles.Forsyth 	vec->genskfrompk = eg_genfrompk;
21637da2899SCharles.Forsyth 	vec->sign = eg_sign;
21737da2899SCharles.Forsyth 	vec->verify = eg_verify;
21837da2899SCharles.Forsyth 
21937da2899SCharles.Forsyth 	vec->skfree = eg_freepriv;
22037da2899SCharles.Forsyth 	vec->pkfree = eg_freepub;
22137da2899SCharles.Forsyth 	vec->sigfree = eg_freesig;
22237da2899SCharles.Forsyth 
22337da2899SCharles.Forsyth 	return vec;
22437da2899SCharles.Forsyth }
225