xref: /inferno-os/libkeyring/rsaalg.c (revision ef0540196bd7163f29ec3259e3fefb7a12d659dc)
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[] = { "n", "ek", nil };
11 static char*	skattr[] = { "n", "ek", "!dk", "!p", "!q", "!kp", "!kq", "!c2", nil };
12 static char*	sigattr[] = { "val", nil };
13 
14 static void*
15 rsa_str2sk(char *str, char **strp)
16 {
17 	RSApriv *rsa;
18 	char *p;
19 
20 	rsa = rsaprivalloc();
21 	rsa->pub.n = base64tobig(str, &p);
22 	rsa->pub.ek = base64tobig(p, &p);
23 	rsa->dk = base64tobig(p, &p);
24 	rsa->p = base64tobig(p, &p);
25 	rsa->q = base64tobig(p, &p);
26 	rsa->kp = base64tobig(p, &p);
27 	rsa->kq = base64tobig(p, &p);
28 	rsa->c2 = base64tobig(p, &p);
29 	if(strp)
30 		*strp = p;
31 
32 	return rsa;
33 }
34 
35 static void*
36 rsa_str2pk(char *str, char **strp)
37 {
38 	RSApub *rsa;
39 	char *p;
40 
41 	rsa = rsapuballoc();
42 	rsa->n = base64tobig(str, &p);
43 	rsa->ek = base64tobig(p, &p);
44 	if(strp)
45 		*strp = p;
46 
47 	return rsa;
48 }
49 
50 static void*
51 rsa_str2sig(char *str, char **strp)
52 {
53 	BigInt rsa;
54 	char *p;
55 
56 	rsa = base64tobig(str, &p);
57 	if(strp)
58 		*strp = p;
59 	return rsa;
60 }
61 
62 static int
63 rsa_sk2str(void *vrsa, char *buf, int len)
64 {
65 	RSApriv *rsa;
66 	char *cp, *ep;
67 
68 	rsa = vrsa;
69 	ep = buf + len - 1;
70 	cp = buf;
71 
72 	cp += snprint(cp, ep - cp, "%U\n", rsa->pub.n);
73 	cp += snprint(cp, ep - cp, "%U\n", rsa->pub.ek);
74 	cp += snprint(cp, ep - cp, "%U\n", rsa->dk);
75 	cp += snprint(cp, ep - cp, "%U\n", rsa->p);
76 	cp += snprint(cp, ep - cp, "%U\n", rsa->q);
77 	cp += snprint(cp, ep - cp, "%U\n", rsa->kp);
78 	cp += snprint(cp, ep - cp, "%U\n", rsa->kq);
79 	cp += snprint(cp, ep - cp, "%U\n", rsa->c2);
80 	*cp = 0;
81 
82 	return cp - buf;
83 }
84 
85 static int
86 rsa_pk2str(void *vrsa, char *buf, int len)
87 {
88 	RSApub *rsa;
89 	char *cp, *ep;
90 
91 	rsa = vrsa;
92 	ep = buf + len - 1;
93 	cp = buf;
94 	cp += snprint(cp, ep - cp, "%U\n", rsa->n);
95 	cp += snprint(cp, ep - cp, "%U\n", rsa->ek);
96 	*cp = 0;
97 
98 	return cp - buf;
99 }
100 
101 static int
102 rsa_sig2str(void *vrsa, char *buf, int len)
103 {
104 	BigInt rsa;
105 	char *cp, *ep;
106 
107 	rsa = vrsa;
108 	ep = buf + len - 1;
109 	cp = buf;
110 
111 	cp += snprint(cp, ep - cp, "%U\n", rsa);
112 	*cp = 0;
113 
114 	return cp - buf;
115 }
116 
117 static void*
118 rsa_sk2pk(void *vs)
119 {
120 	return rsaprivtopub((RSApriv*)vs);
121 }
122 
123 /* generate an rsa secret key */
124 static void*
125 rsa_gen(int len)
126 {
127 	RSApriv *key;
128 
129 	for(;;){
130 		key = rsagen(len, 6, 0);
131 		if(mpsignif(key->pub.n) == len)
132 			return key;
133 		free(key);
134 	}
135 }
136 
137 /* generate an rsa secret key with same params as a public key */
138 static void*
139 rsa_genfrompk(void *vpub)
140 {
141 	RSApub *pub;
142 
143 	pub = vpub;
144 	return rsagen(mpsignif(pub->n), mpsignif(pub->ek), 0);
145 }
146 
147 static void*
148 rsa_sign(BigInt m, void *key)
149 {
150 	return rsadecrypt((RSApriv*)key, m, nil);
151 }
152 
153 static int
154 rsa_verify(BigInt m, void *sig, void *key)
155 {
156 	BigInt t;
157 	int r;
158 
159 	t = rsaencrypt((RSApub*)key, (BigInt)sig, nil);
160 	r = mpcmp(t, m) == 0;
161 	mpfree(t);
162 	return r;
163 }
164 
165 static void
166 rsa_freepriv(void *a)
167 {
168 	rsaprivfree((RSApriv*)a);
169 }
170 
171 static void
172 rsa_freepub(void *a)
173 {
174 	rsapubfree((RSApub*)a);
175 }
176 
177 static void
178 rsa_freesig(void *a)
179 {
180 	mpfree((BigInt)a);
181 }
182 
183 SigAlgVec*
184 rsainit(void)
185 {
186 	SigAlgVec *vec;
187 
188 	vec = malloc(sizeof(SigAlgVec));
189 	if(vec == nil)
190 		return nil;
191 
192 	vec->name = "rsa";
193 
194 	vec->pkattr = pkattr;
195 	vec->skattr = skattr;
196 	vec->sigattr = sigattr;
197 
198 	vec->str2sk = rsa_str2sk;
199 	vec->str2pk = rsa_str2pk;
200 	vec->str2sig = rsa_str2sig;
201 
202 	vec->sk2str = rsa_sk2str;
203 	vec->pk2str = rsa_pk2str;
204 	vec->sig2str = rsa_sig2str;
205 
206 	vec->sk2pk = rsa_sk2pk;
207 
208 	vec->gensk = rsa_gen;
209 	vec->genskfrompk = rsa_genfrompk;
210 	vec->sign = rsa_sign;
211 	vec->verify = rsa_verify;
212 
213 	vec->skfree = rsa_freepriv;
214 	vec->pkfree = rsa_freepub;
215 	vec->sigfree = rsa_freesig;
216 
217 	return vec;
218 }
219