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