xref: /inferno-os/libkeyring/rsaalg.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[] = { "n", "ek", nil };
1137da2899SCharles.Forsyth static char*	skattr[] = { "n", "ek", "!dk", "!p", "!q", "!kp", "!kq", "!c2", nil };
1237da2899SCharles.Forsyth static char*	sigattr[] = { "val", nil };
1337da2899SCharles.Forsyth 
1437da2899SCharles.Forsyth static void*
rsa_str2sk(char * str,char ** strp)1537da2899SCharles.Forsyth rsa_str2sk(char *str, char **strp)
1637da2899SCharles.Forsyth {
1737da2899SCharles.Forsyth 	RSApriv *rsa;
1837da2899SCharles.Forsyth 	char *p;
1937da2899SCharles.Forsyth 
2037da2899SCharles.Forsyth 	rsa = rsaprivalloc();
2137da2899SCharles.Forsyth 	rsa->pub.n = base64tobig(str, &p);
2237da2899SCharles.Forsyth 	rsa->pub.ek = base64tobig(p, &p);
2337da2899SCharles.Forsyth 	rsa->dk = base64tobig(p, &p);
2437da2899SCharles.Forsyth 	rsa->p = base64tobig(p, &p);
2537da2899SCharles.Forsyth 	rsa->q = base64tobig(p, &p);
2637da2899SCharles.Forsyth 	rsa->kp = base64tobig(p, &p);
2737da2899SCharles.Forsyth 	rsa->kq = base64tobig(p, &p);
2837da2899SCharles.Forsyth 	rsa->c2 = base64tobig(p, &p);
2937da2899SCharles.Forsyth 	if(strp)
3037da2899SCharles.Forsyth 		*strp = p;
31032c0afdSforsyth 	if(rsa->pub.n == nil || rsa->pub.ek == nil ||
32032c0afdSforsyth 	   rsa->dk == nil || rsa->p == nil || rsa->q == nil ||
33032c0afdSforsyth 	   rsa->kp == nil || rsa->kq == nil || rsa->c2 == nil){
34032c0afdSforsyth 		rsaprivfree(rsa);
35032c0afdSforsyth 		return nil;
36032c0afdSforsyth 	}
3737da2899SCharles.Forsyth 
3837da2899SCharles.Forsyth 	return rsa;
3937da2899SCharles.Forsyth }
4037da2899SCharles.Forsyth 
4137da2899SCharles.Forsyth static void*
rsa_str2pk(char * str,char ** strp)4237da2899SCharles.Forsyth rsa_str2pk(char *str, char **strp)
4337da2899SCharles.Forsyth {
4437da2899SCharles.Forsyth 	RSApub *rsa;
4537da2899SCharles.Forsyth 	char *p;
4637da2899SCharles.Forsyth 
4737da2899SCharles.Forsyth 	rsa = rsapuballoc();
4837da2899SCharles.Forsyth 	rsa->n = base64tobig(str, &p);
4937da2899SCharles.Forsyth 	rsa->ek = base64tobig(p, &p);
5037da2899SCharles.Forsyth 	if(strp)
5137da2899SCharles.Forsyth 		*strp = p;
52032c0afdSforsyth 	if(rsa->n == nil || rsa->ek == nil){
53032c0afdSforsyth 		rsapubfree(rsa);
54032c0afdSforsyth 		return nil;
55032c0afdSforsyth 	}
5637da2899SCharles.Forsyth 
5737da2899SCharles.Forsyth 	return rsa;
5837da2899SCharles.Forsyth }
5937da2899SCharles.Forsyth 
6037da2899SCharles.Forsyth static void*
rsa_str2sig(char * str,char ** strp)6137da2899SCharles.Forsyth rsa_str2sig(char *str, char **strp)
6237da2899SCharles.Forsyth {
6331a18a69SCharles.Forsyth 	mpint *rsa;
6437da2899SCharles.Forsyth 	char *p;
6537da2899SCharles.Forsyth 
6637da2899SCharles.Forsyth 	rsa = base64tobig(str, &p);
67032c0afdSforsyth 	if(rsa == nil)
68032c0afdSforsyth 		return nil;
6937da2899SCharles.Forsyth 	if(strp)
7037da2899SCharles.Forsyth 		*strp = p;
7137da2899SCharles.Forsyth 	return rsa;
7237da2899SCharles.Forsyth }
7337da2899SCharles.Forsyth 
7437da2899SCharles.Forsyth static int
rsa_sk2str(void * vrsa,char * buf,int len)7537da2899SCharles.Forsyth rsa_sk2str(void *vrsa, char *buf, int len)
7637da2899SCharles.Forsyth {
7737da2899SCharles.Forsyth 	RSApriv *rsa;
7837da2899SCharles.Forsyth 	char *cp, *ep;
7937da2899SCharles.Forsyth 
8037da2899SCharles.Forsyth 	rsa = vrsa;
8137da2899SCharles.Forsyth 	ep = buf + len - 1;
8237da2899SCharles.Forsyth 	cp = buf;
8337da2899SCharles.Forsyth 
8437da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->pub.n);
8537da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->pub.ek);
8637da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->dk);
8737da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->p);
8837da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->q);
8937da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->kp);
9037da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->kq);
9137da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->c2);
9237da2899SCharles.Forsyth 	*cp = 0;
9337da2899SCharles.Forsyth 
9437da2899SCharles.Forsyth 	return cp - buf;
9537da2899SCharles.Forsyth }
9637da2899SCharles.Forsyth 
9737da2899SCharles.Forsyth static int
rsa_pk2str(void * vrsa,char * buf,int len)9837da2899SCharles.Forsyth rsa_pk2str(void *vrsa, char *buf, int len)
9937da2899SCharles.Forsyth {
10037da2899SCharles.Forsyth 	RSApub *rsa;
10137da2899SCharles.Forsyth 	char *cp, *ep;
10237da2899SCharles.Forsyth 
10337da2899SCharles.Forsyth 	rsa = vrsa;
10437da2899SCharles.Forsyth 	ep = buf + len - 1;
10537da2899SCharles.Forsyth 	cp = buf;
10637da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->n);
10737da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa->ek);
10837da2899SCharles.Forsyth 	*cp = 0;
10937da2899SCharles.Forsyth 
11037da2899SCharles.Forsyth 	return cp - buf;
11137da2899SCharles.Forsyth }
11237da2899SCharles.Forsyth 
11337da2899SCharles.Forsyth static int
rsa_sig2str(void * vrsa,char * buf,int len)11437da2899SCharles.Forsyth rsa_sig2str(void *vrsa, char *buf, int len)
11537da2899SCharles.Forsyth {
11631a18a69SCharles.Forsyth 	mpint *rsa;
11737da2899SCharles.Forsyth 	char *cp, *ep;
11837da2899SCharles.Forsyth 
11937da2899SCharles.Forsyth 	rsa = vrsa;
12037da2899SCharles.Forsyth 	ep = buf + len - 1;
12137da2899SCharles.Forsyth 	cp = buf;
12237da2899SCharles.Forsyth 
12337da2899SCharles.Forsyth 	cp += snprint(cp, ep - cp, "%U\n", rsa);
12437da2899SCharles.Forsyth 	*cp = 0;
12537da2899SCharles.Forsyth 
12637da2899SCharles.Forsyth 	return cp - buf;
12737da2899SCharles.Forsyth }
12837da2899SCharles.Forsyth 
12937da2899SCharles.Forsyth static void*
rsa_sk2pk(void * vs)13037da2899SCharles.Forsyth rsa_sk2pk(void *vs)
13137da2899SCharles.Forsyth {
13237da2899SCharles.Forsyth 	return rsaprivtopub((RSApriv*)vs);
13337da2899SCharles.Forsyth }
13437da2899SCharles.Forsyth 
13537da2899SCharles.Forsyth /* generate an rsa secret key */
13637da2899SCharles.Forsyth static void*
rsa_gen(int len)13737da2899SCharles.Forsyth rsa_gen(int len)
13837da2899SCharles.Forsyth {
1392a409d9cSCharles.Forsyth 	RSApriv *key;
1402a409d9cSCharles.Forsyth 
1412a409d9cSCharles.Forsyth 	for(;;){
1422a409d9cSCharles.Forsyth 		key = rsagen(len, 6, 0);
1432a409d9cSCharles.Forsyth 		if(mpsignif(key->pub.n) == len)
1442a409d9cSCharles.Forsyth 			return key;
1452c445c89SCharles.Forsyth 		rsaprivfree(key);
1462a409d9cSCharles.Forsyth 	}
14737da2899SCharles.Forsyth }
14837da2899SCharles.Forsyth 
14937da2899SCharles.Forsyth /* generate an rsa secret key with same params as a public key */
15037da2899SCharles.Forsyth static void*
rsa_genfrompk(void * vpub)15137da2899SCharles.Forsyth rsa_genfrompk(void *vpub)
15237da2899SCharles.Forsyth {
15337da2899SCharles.Forsyth 	RSApub *pub;
15437da2899SCharles.Forsyth 
15537da2899SCharles.Forsyth 	pub = vpub;
15637da2899SCharles.Forsyth 	return rsagen(mpsignif(pub->n), mpsignif(pub->ek), 0);
15737da2899SCharles.Forsyth }
15837da2899SCharles.Forsyth 
15937da2899SCharles.Forsyth static void*
rsa_sign(mpint * m,void * key)16031a18a69SCharles.Forsyth rsa_sign(mpint* m, void *key)
16137da2899SCharles.Forsyth {
16237da2899SCharles.Forsyth 	return rsadecrypt((RSApriv*)key, m, nil);
16337da2899SCharles.Forsyth }
16437da2899SCharles.Forsyth 
16537da2899SCharles.Forsyth static int
rsa_verify(mpint * m,void * sig,void * key)16631a18a69SCharles.Forsyth rsa_verify(mpint* m, void *sig, void *key)
16737da2899SCharles.Forsyth {
16831a18a69SCharles.Forsyth 	mpint *t;
16937da2899SCharles.Forsyth 	int r;
17037da2899SCharles.Forsyth 
17131a18a69SCharles.Forsyth 	t = rsaencrypt((RSApub*)key, (mpint*)sig, nil);
17237da2899SCharles.Forsyth 	r = mpcmp(t, m) == 0;
17337da2899SCharles.Forsyth 	mpfree(t);
17437da2899SCharles.Forsyth 	return r;
17537da2899SCharles.Forsyth }
17637da2899SCharles.Forsyth 
17737da2899SCharles.Forsyth static void
rsa_freepriv(void * a)17837da2899SCharles.Forsyth rsa_freepriv(void *a)
17937da2899SCharles.Forsyth {
18037da2899SCharles.Forsyth 	rsaprivfree((RSApriv*)a);
18137da2899SCharles.Forsyth }
18237da2899SCharles.Forsyth 
18337da2899SCharles.Forsyth static void
rsa_freepub(void * a)18437da2899SCharles.Forsyth rsa_freepub(void *a)
18537da2899SCharles.Forsyth {
18637da2899SCharles.Forsyth 	rsapubfree((RSApub*)a);
18737da2899SCharles.Forsyth }
18837da2899SCharles.Forsyth 
18937da2899SCharles.Forsyth static void
rsa_freesig(void * a)19037da2899SCharles.Forsyth rsa_freesig(void *a)
19137da2899SCharles.Forsyth {
19231a18a69SCharles.Forsyth 	mpfree(a);
19337da2899SCharles.Forsyth }
19437da2899SCharles.Forsyth 
19537da2899SCharles.Forsyth SigAlgVec*
rsainit(void)19637da2899SCharles.Forsyth rsainit(void)
19737da2899SCharles.Forsyth {
19837da2899SCharles.Forsyth 	SigAlgVec *vec;
19937da2899SCharles.Forsyth 
20037da2899SCharles.Forsyth 	vec = malloc(sizeof(SigAlgVec));
20137da2899SCharles.Forsyth 	if(vec == nil)
20237da2899SCharles.Forsyth 		return nil;
20337da2899SCharles.Forsyth 
20437da2899SCharles.Forsyth 	vec->name = "rsa";
20537da2899SCharles.Forsyth 
20637da2899SCharles.Forsyth 	vec->pkattr = pkattr;
20737da2899SCharles.Forsyth 	vec->skattr = skattr;
20837da2899SCharles.Forsyth 	vec->sigattr = sigattr;
20937da2899SCharles.Forsyth 
21037da2899SCharles.Forsyth 	vec->str2sk = rsa_str2sk;
21137da2899SCharles.Forsyth 	vec->str2pk = rsa_str2pk;
21237da2899SCharles.Forsyth 	vec->str2sig = rsa_str2sig;
21337da2899SCharles.Forsyth 
21437da2899SCharles.Forsyth 	vec->sk2str = rsa_sk2str;
21537da2899SCharles.Forsyth 	vec->pk2str = rsa_pk2str;
21637da2899SCharles.Forsyth 	vec->sig2str = rsa_sig2str;
21737da2899SCharles.Forsyth 
21837da2899SCharles.Forsyth 	vec->sk2pk = rsa_sk2pk;
21937da2899SCharles.Forsyth 
22037da2899SCharles.Forsyth 	vec->gensk = rsa_gen;
22137da2899SCharles.Forsyth 	vec->genskfrompk = rsa_genfrompk;
22237da2899SCharles.Forsyth 	vec->sign = rsa_sign;
22337da2899SCharles.Forsyth 	vec->verify = rsa_verify;
22437da2899SCharles.Forsyth 
22537da2899SCharles.Forsyth 	vec->skfree = rsa_freepriv;
22637da2899SCharles.Forsyth 	vec->pkfree = rsa_freepub;
22737da2899SCharles.Forsyth 	vec->sigfree = rsa_freesig;
22837da2899SCharles.Forsyth 
22937da2899SCharles.Forsyth 	return vec;
23037da2899SCharles.Forsyth }
231