xref: /inferno-os/libkeyring/egalg.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include <lib9.h>
2 #include <kernel.h>
3 #include <isa.h>
4 #include "interp.h"
5 #include "../libinterp/runt.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*
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*
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*
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
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
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
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*
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*
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*
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*
160 eg_sign(mpint* mp, void *key)
161 {
162 	return egsign((EGpriv*)key, mp);
163 }
164 
165 static int
166 eg_verify(mpint* mp, void *sig, void *key)
167 {
168 	return egverify((EGpub*)key, (EGsig*)sig, mp) == 0;
169 }
170 
171 static void
172 eg_freepub(void *a)
173 {
174 	egpubfree((EGpub*)a);
175 }
176 
177 static void
178 eg_freepriv(void *a)
179 {
180 	egprivfree((EGpriv*)a);
181 }
182 
183 static void
184 eg_freesig(void *a)
185 {
186 	egsigfree((EGsig*)a);
187 }
188 
189 SigAlgVec*
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