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