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