1 #include <lib9.h>
2 #include <kernel.h>
3 #include <isa.h>
4 #include "interp.h"
5 #include "../libinterp/keyringif.h"
6 #include "mp.h"
7 #include "libsec.h"
8 #include "keys.h"
9
10 static char* pkattr[] = { "p", "alpha", "key", nil };
11 static char* skattr[] = { "p", "alpha", "key", "!secret", nil };
12 static char* sigattr[] = { "r", "s", nil };
13
14 static void*
eg_str2sk(char * str,char ** strp)15 eg_str2sk(char *str, char **strp)
16 {
17 EGpriv *eg;
18 char *p;
19
20 eg = egprivalloc();
21 eg->pub.p = base64tobig(str, &p);
22 eg->pub.alpha = base64tobig(p, &p);
23 eg->pub.key = base64tobig(p, &p);
24 eg->secret = base64tobig(p, &p);
25 if(strp)
26 *strp = p;
27 if(eg->pub.p == nil || eg->pub.alpha == nil || eg->pub.key == nil || eg->secret == nil){
28 egprivfree(eg);
29 return nil;
30 }
31 return eg;
32 }
33
34 static void*
eg_str2pk(char * str,char ** strp)35 eg_str2pk(char *str, char **strp)
36 {
37 EGpub *eg;
38 char *p;
39
40 eg = egpuballoc();
41 eg->p = base64tobig(str, &p);
42 eg->alpha = base64tobig(p, &p);
43 eg->key = base64tobig(p, &p);
44 if(strp)
45 *strp = p;
46 if(eg->p == nil || eg->alpha == nil || eg->key == nil){
47 egpubfree(eg);
48 return nil;
49 }
50 return eg;
51 }
52
53 static void*
eg_str2sig(char * str,char ** strp)54 eg_str2sig(char *str, char **strp)
55 {
56 EGsig *eg;
57 char *p;
58
59 eg = egsigalloc();
60 eg->r = base64tobig(str, &p);
61 eg->s = base64tobig(p, &p);
62 if(strp)
63 *strp = p;
64 if(eg->r == nil || eg->s == nil){
65 egsigfree(eg);
66 return nil;
67 }
68 return eg;
69 }
70
71 static int
eg_sk2str(void * veg,char * buf,int len)72 eg_sk2str(void *veg, char *buf, int len)
73 {
74 EGpriv *eg;
75 char *cp, *ep;
76
77 eg = (EGpriv*)veg;
78 ep = buf + len - 1;
79 cp = buf;
80
81 cp += snprint(cp, ep - cp, "%U\n", eg->pub.p);
82 cp += snprint(cp, ep - cp, "%U\n", eg->pub.alpha);
83 cp += snprint(cp, ep - cp, "%U\n", eg->pub.key);
84 cp += snprint(cp, ep - cp, "%U\n", eg->secret);
85 *cp = 0;
86
87 return cp - buf;
88 }
89
90 static int
eg_pk2str(void * veg,char * buf,int len)91 eg_pk2str(void *veg, char *buf, int len)
92 {
93 EGpub *eg;
94 char *cp, *ep;
95
96 eg = (EGpub*)veg;
97 ep = buf + len - 1;
98 cp = buf;
99
100 cp += snprint(cp, ep - cp, "%U\n", eg->p);
101 cp += snprint(cp, ep - cp, "%U\n", eg->alpha);
102 cp += snprint(cp, ep - cp, "%U\n", eg->key);
103 *cp = 0;
104
105 return cp - buf;
106 }
107
108 static int
eg_sig2str(void * veg,char * buf,int len)109 eg_sig2str(void *veg, char *buf, int len)
110 {
111 EGsig *eg;
112 char *cp, *ep;
113
114 eg = veg;
115 ep = buf + len - 1;
116 cp = buf;
117
118 cp += snprint(cp, ep - cp, "%U\n", eg->r);
119 cp += snprint(cp, ep - cp, "%U\n", eg->s);
120 *cp = 0;
121
122 return cp - buf;
123 }
124
125 static void*
eg_sk2pk(void * vs)126 eg_sk2pk(void *vs)
127 {
128 return egprivtopub((EGpriv*)vs);
129 }
130
131 /* generate an el gamal secret key with new params */
132 static void*
eg_gen(int len)133 eg_gen(int len)
134 {
135 return eggen(len, 0);
136 }
137
138 /* generate an el gamal secret key with same params as a public key */
139 static void*
eg_genfrompk(void * vpub)140 eg_genfrompk(void *vpub)
141 {
142 EGpub *pub;
143 EGpriv *priv;
144 int nlen;
145
146 pub = vpub;
147 priv = egprivalloc();
148 priv->pub.p = mpcopy(pub->p);
149 priv->pub.alpha = mpcopy(pub->alpha);
150 nlen = mpsignif(pub->p);
151 pub = &priv->pub;
152 pub->key = mpnew(0);
153 priv->secret = mpnew(0);
154 mprand(nlen-1, genrandom, priv->secret);
155 mpexp(pub->alpha, priv->secret, pub->p, pub->key);
156 return priv;
157 }
158
159 static void*
eg_sign(mpint * mp,void * key)160 eg_sign(mpint* mp, void *key)
161 {
162 return egsign((EGpriv*)key, mp);
163 }
164
165 static int
eg_verify(mpint * mp,void * sig,void * key)166 eg_verify(mpint* mp, void *sig, void *key)
167 {
168 return egverify((EGpub*)key, (EGsig*)sig, mp) == 0;
169 }
170
171 static void
eg_freepub(void * a)172 eg_freepub(void *a)
173 {
174 egpubfree((EGpub*)a);
175 }
176
177 static void
eg_freepriv(void * a)178 eg_freepriv(void *a)
179 {
180 egprivfree((EGpriv*)a);
181 }
182
183 static void
eg_freesig(void * a)184 eg_freesig(void *a)
185 {
186 egsigfree((EGsig*)a);
187 }
188
189 SigAlgVec*
elgamalinit(void)190 elgamalinit(void)
191 {
192 SigAlgVec *vec;
193
194 vec = malloc(sizeof(SigAlgVec));
195 if(vec == nil)
196 return nil;
197
198 vec->name = "elgamal";
199
200 vec->pkattr = pkattr;
201 vec->skattr = skattr;
202 vec->sigattr = sigattr;
203
204 vec->str2sk = eg_str2sk;
205 vec->str2pk = eg_str2pk;
206 vec->str2sig = eg_str2sig;
207
208 vec->sk2str = eg_sk2str;
209 vec->pk2str = eg_pk2str;
210 vec->sig2str = eg_sig2str;
211
212 vec->sk2pk = eg_sk2pk;
213
214 vec->gensk = eg_gen;
215 vec->genskfrompk = eg_genfrompk;
216 vec->sign = eg_sign;
217 vec->verify = eg_verify;
218
219 vec->skfree = eg_freepriv;
220 vec->pkfree = eg_freepub;
221 vec->sigfree = eg_freesig;
222
223 return vec;
224 }
225