1*7de2b42dSforsyth #include "lib9.h"
2*7de2b42dSforsyth #include "kernel.h"
3*7de2b42dSforsyth #include <isa.h>
4*7de2b42dSforsyth #include "interp.h"
5*7de2b42dSforsyth #include "runt.h"
6*7de2b42dSforsyth #include "cryptmod.h"
7*7de2b42dSforsyth #include <mp.h>
8*7de2b42dSforsyth #include <libsec.h>
9*7de2b42dSforsyth #include "pool.h"
10*7de2b42dSforsyth #include "raise.h"
11*7de2b42dSforsyth #include "ipint.h"
12*7de2b42dSforsyth
13*7de2b42dSforsyth #define MPX(x) checkIPint((void*)(x))
14*7de2b42dSforsyth
15*7de2b42dSforsyth static Type* TDigestState;
16*7de2b42dSforsyth static Type* TAESstate;
17*7de2b42dSforsyth static Type* TDESstate;
18*7de2b42dSforsyth static Type* TIDEAstate;
19*7de2b42dSforsyth static Type* TBFstate;
20*7de2b42dSforsyth static Type* TRC4state;
21*7de2b42dSforsyth
22*7de2b42dSforsyth static Type* TSKdsa;
23*7de2b42dSforsyth static Type* TPKdsa;
24*7de2b42dSforsyth static Type* TPKsigdsa;
25*7de2b42dSforsyth static Type* TSKeg;
26*7de2b42dSforsyth static Type* TPKeg;
27*7de2b42dSforsyth static Type* TPKsigeg;
28*7de2b42dSforsyth static Type* TSKrsa;
29*7de2b42dSforsyth static Type* TPKrsa;
30*7de2b42dSforsyth static Type* TPKsigrsa;
31*7de2b42dSforsyth
32*7de2b42dSforsyth static uchar DigestStatemap[] = Crypt_DigestState_map;
33*7de2b42dSforsyth static uchar AESstatemap[] = Crypt_AESstate_map;
34*7de2b42dSforsyth static uchar DESstatemap[] = Crypt_DESstate_map;
35*7de2b42dSforsyth static uchar IDEAstatemap[] = Crypt_IDEAstate_map;
36*7de2b42dSforsyth static uchar BFstatemap[] = Crypt_BFstate_map;
37*7de2b42dSforsyth static uchar RC4statemap[] = Crypt_RC4state_map;
38*7de2b42dSforsyth
39*7de2b42dSforsyth static uchar DSAskmap[] = Crypt_SK_DSA_map;
40*7de2b42dSforsyth static uchar DSApkmap[] = Crypt_PK_DSA_map;
41*7de2b42dSforsyth static uchar DSAsigmap[] = Crypt_PKsig_DSA_map;
42*7de2b42dSforsyth static uchar EGskmap[] = Crypt_SK_Elgamal_map;
43*7de2b42dSforsyth static uchar EGpkmap[] = Crypt_PK_Elgamal_map;
44*7de2b42dSforsyth static uchar EGsigmap[] = Crypt_PKsig_Elgamal_map;
45*7de2b42dSforsyth static uchar RSAskmap[] = Crypt_SK_RSA_map;
46*7de2b42dSforsyth static uchar RSApkmap[] = Crypt_PK_RSA_map;
47*7de2b42dSforsyth static uchar RSAsigmap[] = Crypt_PKsig_RSA_map;
48*7de2b42dSforsyth
49*7de2b42dSforsyth static char exBadBsize[] = "data not multiple of block size";
50*7de2b42dSforsyth static char exBadKey[] = "bad encryption key";
51*7de2b42dSforsyth static char exBadDigest[] = "bad digest value";
52*7de2b42dSforsyth static char exBadIvec[] = "bad ivec";
53*7de2b42dSforsyth static char exBadState[] = "bad encryption state";
54*7de2b42dSforsyth
55*7de2b42dSforsyth /*
56*7de2b42dSforsyth * these structures reveal the C state of Limbo adts in crypt.m
57*7de2b42dSforsyth */
58*7de2b42dSforsyth
59*7de2b42dSforsyth typedef struct XDigestState XDigestState;
60*7de2b42dSforsyth typedef struct XAESstate XAESstate;
61*7de2b42dSforsyth typedef struct XDESstate XDESstate;
62*7de2b42dSforsyth typedef struct XIDEAstate XIDEAstate;
63*7de2b42dSforsyth typedef struct XBFstate XBFstate;
64*7de2b42dSforsyth typedef struct XRC4state XRC4state;
65*7de2b42dSforsyth
66*7de2b42dSforsyth /* digest state */
67*7de2b42dSforsyth struct XDigestState
68*7de2b42dSforsyth {
69*7de2b42dSforsyth Crypt_DigestState x;
70*7de2b42dSforsyth DigestState state;
71*7de2b42dSforsyth };
72*7de2b42dSforsyth
73*7de2b42dSforsyth /* AES state */
74*7de2b42dSforsyth struct XAESstate
75*7de2b42dSforsyth {
76*7de2b42dSforsyth Crypt_AESstate x;
77*7de2b42dSforsyth AESstate state;
78*7de2b42dSforsyth };
79*7de2b42dSforsyth
80*7de2b42dSforsyth /* DES state */
81*7de2b42dSforsyth struct XDESstate
82*7de2b42dSforsyth {
83*7de2b42dSforsyth Crypt_DESstate x;
84*7de2b42dSforsyth DESstate state;
85*7de2b42dSforsyth };
86*7de2b42dSforsyth
87*7de2b42dSforsyth /* IDEA state */
88*7de2b42dSforsyth struct XIDEAstate
89*7de2b42dSforsyth {
90*7de2b42dSforsyth Crypt_IDEAstate x;
91*7de2b42dSforsyth IDEAstate state;
92*7de2b42dSforsyth };
93*7de2b42dSforsyth
94*7de2b42dSforsyth /* BF state */
95*7de2b42dSforsyth struct XBFstate
96*7de2b42dSforsyth {
97*7de2b42dSforsyth Crypt_BFstate x;
98*7de2b42dSforsyth BFstate state;
99*7de2b42dSforsyth };
100*7de2b42dSforsyth
101*7de2b42dSforsyth /* RC4 state */
102*7de2b42dSforsyth struct XRC4state
103*7de2b42dSforsyth {
104*7de2b42dSforsyth Crypt_RC4state x;
105*7de2b42dSforsyth RC4state state;
106*7de2b42dSforsyth };
107*7de2b42dSforsyth
108*7de2b42dSforsyth static Crypt_PK*
newPK(Type * t,int pick)109*7de2b42dSforsyth newPK(Type *t, int pick)
110*7de2b42dSforsyth {
111*7de2b42dSforsyth Heap *h;
112*7de2b42dSforsyth Crypt_PK *sk;
113*7de2b42dSforsyth
114*7de2b42dSforsyth h = heap(t);
115*7de2b42dSforsyth sk = H2D(Crypt_PK*, h);
116*7de2b42dSforsyth sk->pick = pick;
117*7de2b42dSforsyth return sk;
118*7de2b42dSforsyth }
119*7de2b42dSforsyth
120*7de2b42dSforsyth static Crypt_SK*
newSK(Crypt_SK ** ret,Type * t,int pick)121*7de2b42dSforsyth newSK(Crypt_SK** ret, Type *t, int pick)
122*7de2b42dSforsyth {
123*7de2b42dSforsyth Heap *h;
124*7de2b42dSforsyth Crypt_SK *sk;
125*7de2b42dSforsyth
126*7de2b42dSforsyth h = heap(t);
127*7de2b42dSforsyth sk = H2D(Crypt_SK*, h);
128*7de2b42dSforsyth sk->pick = pick;
129*7de2b42dSforsyth if(ret != nil)
130*7de2b42dSforsyth *ret = sk;
131*7de2b42dSforsyth switch(pick){
132*7de2b42dSforsyth case Crypt_PK_RSA:
133*7de2b42dSforsyth sk->u.RSA.pk = newPK(TPKrsa, Crypt_PK_RSA);
134*7de2b42dSforsyth break;
135*7de2b42dSforsyth case Crypt_PK_Elgamal:
136*7de2b42dSforsyth sk->u.Elgamal.pk = newPK(TPKeg, Crypt_PK_Elgamal);
137*7de2b42dSforsyth break;
138*7de2b42dSforsyth case Crypt_PK_DSA:
139*7de2b42dSforsyth sk->u.DSA.pk = newPK(TPKdsa, Crypt_PK_DSA);
140*7de2b42dSforsyth break;
141*7de2b42dSforsyth default:
142*7de2b42dSforsyth error(exType);
143*7de2b42dSforsyth }
144*7de2b42dSforsyth return sk;
145*7de2b42dSforsyth }
146*7de2b42dSforsyth
147*7de2b42dSforsyth static Crypt_PKsig*
newPKsig(Type * t,int pick)148*7de2b42dSforsyth newPKsig(Type *t, int pick)
149*7de2b42dSforsyth {
150*7de2b42dSforsyth Heap *h;
151*7de2b42dSforsyth Crypt_PKsig *s;
152*7de2b42dSforsyth
153*7de2b42dSforsyth h = heap(t);
154*7de2b42dSforsyth s = H2D(Crypt_PKsig*, h);
155*7de2b42dSforsyth s->pick = pick;
156*7de2b42dSforsyth return s;
157*7de2b42dSforsyth }
158*7de2b42dSforsyth
159*7de2b42dSforsyth static IPints_IPint*
ipcopymp(mpint * b)160*7de2b42dSforsyth ipcopymp(mpint* b)
161*7de2b42dSforsyth {
162*7de2b42dSforsyth if(b == nil)
163*7de2b42dSforsyth return H;
164*7de2b42dSforsyth return newIPint(mpcopy(b));
165*7de2b42dSforsyth }
166*7de2b42dSforsyth
167*7de2b42dSforsyth /*
168*7de2b42dSforsyth * digests
169*7de2b42dSforsyth */
170*7de2b42dSforsyth void
DigestState_copy(void * fp)171*7de2b42dSforsyth DigestState_copy(void *fp)
172*7de2b42dSforsyth {
173*7de2b42dSforsyth F_DigestState_copy *f;
174*7de2b42dSforsyth Heap *h;
175*7de2b42dSforsyth XDigestState *ds, *ods;
176*7de2b42dSforsyth void *r;
177*7de2b42dSforsyth
178*7de2b42dSforsyth f = fp;
179*7de2b42dSforsyth r = *f->ret;
180*7de2b42dSforsyth *f->ret = H;
181*7de2b42dSforsyth destroy(r);
182*7de2b42dSforsyth
183*7de2b42dSforsyth if(f->d != H){
184*7de2b42dSforsyth ods = checktype(f->d, TDigestState, "DigestState", 0);
185*7de2b42dSforsyth h = heap(TDigestState);
186*7de2b42dSforsyth ds = H2D(XDigestState*, h);
187*7de2b42dSforsyth memmove(&ds->state, &ods->state, sizeof(ds->state));
188*7de2b42dSforsyth *f->ret = (Crypt_DigestState*)ds;
189*7de2b42dSforsyth }
190*7de2b42dSforsyth }
191*7de2b42dSforsyth
192*7de2b42dSforsyth static Crypt_DigestState*
crypt_digest_x(Array * buf,int n,Array * digest,int dlen,Crypt_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,DigestState *))193*7de2b42dSforsyth crypt_digest_x(Array *buf, int n, Array *digest, int dlen, Crypt_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, DigestState*))
194*7de2b42dSforsyth {
195*7de2b42dSforsyth Heap *h;
196*7de2b42dSforsyth XDigestState *ds;
197*7de2b42dSforsyth uchar *cbuf, *cdigest;
198*7de2b42dSforsyth
199*7de2b42dSforsyth if(buf != H){
200*7de2b42dSforsyth if(n > buf->len)
201*7de2b42dSforsyth n = buf->len;
202*7de2b42dSforsyth cbuf = buf->data;
203*7de2b42dSforsyth }else{
204*7de2b42dSforsyth if(n != 0)
205*7de2b42dSforsyth error(exInval);
206*7de2b42dSforsyth cbuf = nil;
207*7de2b42dSforsyth }
208*7de2b42dSforsyth
209*7de2b42dSforsyth if(digest != H){
210*7de2b42dSforsyth if(digest->len < dlen)
211*7de2b42dSforsyth error(exBadDigest);
212*7de2b42dSforsyth cdigest = digest->data;
213*7de2b42dSforsyth } else
214*7de2b42dSforsyth cdigest = nil;
215*7de2b42dSforsyth
216*7de2b42dSforsyth if(state == H){
217*7de2b42dSforsyth h = heap(TDigestState);
218*7de2b42dSforsyth ds = H2D(XDigestState*, h);
219*7de2b42dSforsyth memset(&ds->state, 0, sizeof(ds->state));
220*7de2b42dSforsyth } else
221*7de2b42dSforsyth ds = checktype(state, TDigestState, "DigestState", 1);
222*7de2b42dSforsyth
223*7de2b42dSforsyth (*fn)(cbuf, n, cdigest, &ds->state);
224*7de2b42dSforsyth
225*7de2b42dSforsyth return (Crypt_DigestState*)ds;
226*7de2b42dSforsyth }
227*7de2b42dSforsyth
228*7de2b42dSforsyth void
Crypt_sha1(void * fp)229*7de2b42dSforsyth Crypt_sha1(void *fp)
230*7de2b42dSforsyth {
231*7de2b42dSforsyth F_Crypt_sha1 *f;
232*7de2b42dSforsyth void *r;
233*7de2b42dSforsyth
234*7de2b42dSforsyth f = fp;
235*7de2b42dSforsyth r = *f->ret;
236*7de2b42dSforsyth *f->ret = H;
237*7de2b42dSforsyth destroy(r);
238*7de2b42dSforsyth
239*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA1dlen, f->state, sha1);
240*7de2b42dSforsyth }
241*7de2b42dSforsyth
242*7de2b42dSforsyth void
Crypt_sha224(void * fp)243*7de2b42dSforsyth Crypt_sha224(void *fp)
244*7de2b42dSforsyth {
245*7de2b42dSforsyth F_Crypt_sha224 *f;
246*7de2b42dSforsyth void *r;
247*7de2b42dSforsyth
248*7de2b42dSforsyth f = fp;
249*7de2b42dSforsyth r = *f->ret;
250*7de2b42dSforsyth *f->ret = H;
251*7de2b42dSforsyth destroy(r);
252*7de2b42dSforsyth
253*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA224dlen, f->state, sha224);
254*7de2b42dSforsyth }
255*7de2b42dSforsyth
256*7de2b42dSforsyth void
Crypt_sha256(void * fp)257*7de2b42dSforsyth Crypt_sha256(void *fp)
258*7de2b42dSforsyth {
259*7de2b42dSforsyth F_Crypt_sha256 *f;
260*7de2b42dSforsyth void *r;
261*7de2b42dSforsyth
262*7de2b42dSforsyth f = fp;
263*7de2b42dSforsyth r = *f->ret;
264*7de2b42dSforsyth *f->ret = H;
265*7de2b42dSforsyth destroy(r);
266*7de2b42dSforsyth
267*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA256dlen, f->state, sha256);
268*7de2b42dSforsyth }
269*7de2b42dSforsyth
270*7de2b42dSforsyth void
Crypt_sha384(void * fp)271*7de2b42dSforsyth Crypt_sha384(void *fp)
272*7de2b42dSforsyth {
273*7de2b42dSforsyth F_Crypt_sha384 *f;
274*7de2b42dSforsyth void *r;
275*7de2b42dSforsyth
276*7de2b42dSforsyth f = fp;
277*7de2b42dSforsyth r = *f->ret;
278*7de2b42dSforsyth *f->ret = H;
279*7de2b42dSforsyth destroy(r);
280*7de2b42dSforsyth
281*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA384dlen, f->state, sha384);
282*7de2b42dSforsyth }
283*7de2b42dSforsyth
284*7de2b42dSforsyth void
Crypt_sha512(void * fp)285*7de2b42dSforsyth Crypt_sha512(void *fp)
286*7de2b42dSforsyth {
287*7de2b42dSforsyth F_Crypt_sha512 *f;
288*7de2b42dSforsyth void *r;
289*7de2b42dSforsyth
290*7de2b42dSforsyth f = fp;
291*7de2b42dSforsyth r = *f->ret;
292*7de2b42dSforsyth *f->ret = H;
293*7de2b42dSforsyth destroy(r);
294*7de2b42dSforsyth
295*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, SHA512dlen, f->state, sha512);
296*7de2b42dSforsyth }
297*7de2b42dSforsyth
298*7de2b42dSforsyth void
Crypt_md5(void * fp)299*7de2b42dSforsyth Crypt_md5(void *fp)
300*7de2b42dSforsyth {
301*7de2b42dSforsyth F_Crypt_md5 *f;
302*7de2b42dSforsyth void *r;
303*7de2b42dSforsyth
304*7de2b42dSforsyth f = fp;
305*7de2b42dSforsyth r = *f->ret;
306*7de2b42dSforsyth *f->ret = H;
307*7de2b42dSforsyth destroy(r);
308*7de2b42dSforsyth
309*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, MD5dlen, f->state, md5);
310*7de2b42dSforsyth }
311*7de2b42dSforsyth
312*7de2b42dSforsyth void
Crypt_md4(void * fp)313*7de2b42dSforsyth Crypt_md4(void *fp)
314*7de2b42dSforsyth {
315*7de2b42dSforsyth F_Crypt_md4 *f;
316*7de2b42dSforsyth void *r;
317*7de2b42dSforsyth
318*7de2b42dSforsyth f = fp;
319*7de2b42dSforsyth r = *f->ret;
320*7de2b42dSforsyth *f->ret = H;
321*7de2b42dSforsyth destroy(r);
322*7de2b42dSforsyth
323*7de2b42dSforsyth *f->ret = crypt_digest_x(f->buf, f->n, f->digest, MD4dlen, f->state, md4);
324*7de2b42dSforsyth }
325*7de2b42dSforsyth
326*7de2b42dSforsyth static Crypt_DigestState*
crypt_hmac_x(Array * data,int n,Array * key,Array * digest,int dlen,Crypt_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,ulong,uchar *,DigestState *))327*7de2b42dSforsyth crypt_hmac_x(Array *data, int n, Array *key, Array *digest, int dlen, Crypt_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*))
328*7de2b42dSforsyth {
329*7de2b42dSforsyth Heap *h;
330*7de2b42dSforsyth XDigestState *ds;
331*7de2b42dSforsyth uchar *cdata, *cdigest;
332*7de2b42dSforsyth
333*7de2b42dSforsyth if(data != H){
334*7de2b42dSforsyth if(n > data->len)
335*7de2b42dSforsyth n = data->len;
336*7de2b42dSforsyth cdata = data->data;
337*7de2b42dSforsyth }else{
338*7de2b42dSforsyth if(n != 0)
339*7de2b42dSforsyth error(exInval);
340*7de2b42dSforsyth cdata = nil;
341*7de2b42dSforsyth }
342*7de2b42dSforsyth
343*7de2b42dSforsyth if(key == H || key->len > 64)
344*7de2b42dSforsyth error(exBadKey);
345*7de2b42dSforsyth
346*7de2b42dSforsyth if(digest != H){
347*7de2b42dSforsyth if(digest->len < dlen)
348*7de2b42dSforsyth error(exBadDigest);
349*7de2b42dSforsyth cdigest = digest->data;
350*7de2b42dSforsyth } else
351*7de2b42dSforsyth cdigest = nil;
352*7de2b42dSforsyth
353*7de2b42dSforsyth if(state == H){
354*7de2b42dSforsyth h = heap(TDigestState);
355*7de2b42dSforsyth ds = H2D(XDigestState*, h);
356*7de2b42dSforsyth memset(&ds->state, 0, sizeof(ds->state));
357*7de2b42dSforsyth } else
358*7de2b42dSforsyth ds = checktype(state, TDigestState, "DigestState", 1);
359*7de2b42dSforsyth
360*7de2b42dSforsyth (*fn)(cdata, n, key->data, key->len, cdigest, &ds->state);
361*7de2b42dSforsyth
362*7de2b42dSforsyth return (Crypt_DigestState*)ds;
363*7de2b42dSforsyth }
364*7de2b42dSforsyth
365*7de2b42dSforsyth void
Crypt_hmac_sha1(void * fp)366*7de2b42dSforsyth Crypt_hmac_sha1(void *fp)
367*7de2b42dSforsyth {
368*7de2b42dSforsyth F_Crypt_hmac_sha1 *f;
369*7de2b42dSforsyth void *r;
370*7de2b42dSforsyth
371*7de2b42dSforsyth f = fp;
372*7de2b42dSforsyth r = *f->ret;
373*7de2b42dSforsyth *f->ret = H;
374*7de2b42dSforsyth destroy(r);
375*7de2b42dSforsyth *f->ret = crypt_hmac_x(f->data, f->n, f->key, f->digest, SHA1dlen, f->state, hmac_sha1);
376*7de2b42dSforsyth }
377*7de2b42dSforsyth
378*7de2b42dSforsyth void
Crypt_hmac_md5(void * fp)379*7de2b42dSforsyth Crypt_hmac_md5(void *fp)
380*7de2b42dSforsyth {
381*7de2b42dSforsyth F_Crypt_hmac_md5 *f;
382*7de2b42dSforsyth void *r;
383*7de2b42dSforsyth
384*7de2b42dSforsyth f = fp;
385*7de2b42dSforsyth r = *f->ret;
386*7de2b42dSforsyth *f->ret = H;
387*7de2b42dSforsyth destroy(r);
388*7de2b42dSforsyth *f->ret = crypt_hmac_x(f->data, f->n, f->key, f->digest, MD5dlen, f->state, hmac_md5);
389*7de2b42dSforsyth }
390*7de2b42dSforsyth
391*7de2b42dSforsyth void
Crypt_dhparams(void * fp)392*7de2b42dSforsyth Crypt_dhparams(void *fp)
393*7de2b42dSforsyth {
394*7de2b42dSforsyth F_Crypt_dhparams *f;
395*7de2b42dSforsyth mpint *p, *alpha;
396*7de2b42dSforsyth void *v;
397*7de2b42dSforsyth
398*7de2b42dSforsyth f = fp;
399*7de2b42dSforsyth v = f->ret->t0;
400*7de2b42dSforsyth f->ret->t0 = H;
401*7de2b42dSforsyth destroy(v);
402*7de2b42dSforsyth v = f->ret->t1;
403*7de2b42dSforsyth f->ret->t1 = H;
404*7de2b42dSforsyth destroy(v);
405*7de2b42dSforsyth
406*7de2b42dSforsyth p = mpnew(0);
407*7de2b42dSforsyth alpha = mpnew(0);
408*7de2b42dSforsyth release();
409*7de2b42dSforsyth if(f->nbits == 1024)
410*7de2b42dSforsyth DSAprimes(alpha, p, nil);
411*7de2b42dSforsyth else
412*7de2b42dSforsyth gensafeprime(p, alpha, f->nbits, 0);
413*7de2b42dSforsyth acquire();
414*7de2b42dSforsyth f->ret->t0 = newIPint(alpha);
415*7de2b42dSforsyth f->ret->t1 = newIPint(p);
416*7de2b42dSforsyth }
417*7de2b42dSforsyth
418*7de2b42dSforsyth void
cryptmodinit(void)419*7de2b42dSforsyth cryptmodinit(void)
420*7de2b42dSforsyth {
421*7de2b42dSforsyth ipintsmodinit(); /* TIPint */
422*7de2b42dSforsyth
423*7de2b42dSforsyth TDigestState = dtype(freeheap, sizeof(XDigestState), DigestStatemap, sizeof(DigestStatemap));
424*7de2b42dSforsyth TAESstate = dtype(freeheap, sizeof(XAESstate), AESstatemap, sizeof(AESstatemap));
425*7de2b42dSforsyth TDESstate = dtype(freeheap, sizeof(XDESstate), DESstatemap, sizeof(DESstatemap));
426*7de2b42dSforsyth TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap, sizeof(IDEAstatemap));
427*7de2b42dSforsyth TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap, sizeof(BFstatemap));
428*7de2b42dSforsyth TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap, sizeof(RC4statemap));
429*7de2b42dSforsyth
430*7de2b42dSforsyth TSKdsa = dtype(freeheap, Crypt_SK_DSA_size, DSAskmap, sizeof(DSAskmap));
431*7de2b42dSforsyth TPKdsa = dtype(freeheap, Crypt_PK_DSA_size, DSApkmap, sizeof(DSApkmap));
432*7de2b42dSforsyth TPKsigdsa = dtype(freeheap, Crypt_PKsig_DSA_size, DSAsigmap, sizeof(DSAsigmap));
433*7de2b42dSforsyth TSKeg = dtype(freeheap, Crypt_SK_Elgamal_size, EGskmap, sizeof(EGskmap));
434*7de2b42dSforsyth TPKeg = dtype(freeheap, Crypt_PK_Elgamal_size, EGpkmap, sizeof(EGpkmap));
435*7de2b42dSforsyth TPKsigeg = dtype(freeheap, Crypt_PKsig_Elgamal_size, EGsigmap, sizeof(EGsigmap));
436*7de2b42dSforsyth TSKrsa = dtype(freeheap, Crypt_SK_RSA_size, RSAskmap, sizeof(RSAskmap));
437*7de2b42dSforsyth TPKrsa = dtype(freeheap, Crypt_PK_RSA_size, RSApkmap, sizeof(RSApkmap));
438*7de2b42dSforsyth TPKsigrsa = dtype(freeheap, Crypt_PKsig_RSA_size, RSAsigmap, sizeof(RSAsigmap));
439*7de2b42dSforsyth
440*7de2b42dSforsyth builtinmod("$Crypt", Cryptmodtab, Cryptmodlen);
441*7de2b42dSforsyth }
442*7de2b42dSforsyth
443*7de2b42dSforsyth void
Crypt_dessetup(void * fp)444*7de2b42dSforsyth Crypt_dessetup(void *fp)
445*7de2b42dSforsyth {
446*7de2b42dSforsyth F_Crypt_dessetup *f;
447*7de2b42dSforsyth Heap *h;
448*7de2b42dSforsyth XDESstate *ds;
449*7de2b42dSforsyth uchar *ivec;
450*7de2b42dSforsyth void *v;
451*7de2b42dSforsyth
452*7de2b42dSforsyth f = fp;
453*7de2b42dSforsyth v = *f->ret;
454*7de2b42dSforsyth *f->ret = H;
455*7de2b42dSforsyth destroy(v);
456*7de2b42dSforsyth
457*7de2b42dSforsyth if(f->key == H)
458*7de2b42dSforsyth error(exNilref);
459*7de2b42dSforsyth if(f->key->len < 8)
460*7de2b42dSforsyth error(exBadKey);
461*7de2b42dSforsyth if(f->ivec != H){
462*7de2b42dSforsyth if(f->ivec->len < 8)
463*7de2b42dSforsyth error(exBadIvec);
464*7de2b42dSforsyth ivec = f->ivec->data;
465*7de2b42dSforsyth }else
466*7de2b42dSforsyth ivec = nil;
467*7de2b42dSforsyth
468*7de2b42dSforsyth h = heap(TDESstate);
469*7de2b42dSforsyth ds = H2D(XDESstate*, h);
470*7de2b42dSforsyth setupDESstate(&ds->state, f->key->data, ivec);
471*7de2b42dSforsyth
472*7de2b42dSforsyth *f->ret = (Crypt_DESstate*)ds;
473*7de2b42dSforsyth }
474*7de2b42dSforsyth
475*7de2b42dSforsyth void
Crypt_desecb(void * fp)476*7de2b42dSforsyth Crypt_desecb(void *fp)
477*7de2b42dSforsyth {
478*7de2b42dSforsyth F_Crypt_desecb *f;
479*7de2b42dSforsyth XDESstate *ds;
480*7de2b42dSforsyth int i;
481*7de2b42dSforsyth uchar *p;
482*7de2b42dSforsyth
483*7de2b42dSforsyth f = fp;
484*7de2b42dSforsyth
485*7de2b42dSforsyth if(f->buf == H)
486*7de2b42dSforsyth return;
487*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
488*7de2b42dSforsyth error(exBounds);
489*7de2b42dSforsyth if(f->n & 7)
490*7de2b42dSforsyth error(exBadBsize);
491*7de2b42dSforsyth
492*7de2b42dSforsyth ds = checktype(f->state, TDESstate, exBadState, 0);
493*7de2b42dSforsyth p = f->buf->data;
494*7de2b42dSforsyth
495*7de2b42dSforsyth for(i = 8; i <= f->n; i += 8, p += 8)
496*7de2b42dSforsyth block_cipher(ds->state.expanded, p, f->direction);
497*7de2b42dSforsyth }
498*7de2b42dSforsyth
499*7de2b42dSforsyth void
Crypt_descbc(void * fp)500*7de2b42dSforsyth Crypt_descbc(void *fp)
501*7de2b42dSforsyth {
502*7de2b42dSforsyth F_Crypt_descbc *f;
503*7de2b42dSforsyth XDESstate *ds;
504*7de2b42dSforsyth uchar *p, *ep, *ip, *p2, *eip;
505*7de2b42dSforsyth uchar tmp[8];
506*7de2b42dSforsyth
507*7de2b42dSforsyth f = fp;
508*7de2b42dSforsyth
509*7de2b42dSforsyth if(f->buf == H)
510*7de2b42dSforsyth return;
511*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
512*7de2b42dSforsyth error(exBounds);
513*7de2b42dSforsyth if(f->n & 7)
514*7de2b42dSforsyth error(exBadBsize);
515*7de2b42dSforsyth
516*7de2b42dSforsyth ds = checktype(f->state, TDESstate, exBadState, 0);
517*7de2b42dSforsyth p = f->buf->data;
518*7de2b42dSforsyth
519*7de2b42dSforsyth if(f->direction == 0){
520*7de2b42dSforsyth for(ep = p + f->n; p < ep; p += 8){
521*7de2b42dSforsyth p2 = p;
522*7de2b42dSforsyth ip = ds->state.ivec;
523*7de2b42dSforsyth for(eip = ip+8; ip < eip; )
524*7de2b42dSforsyth *p2++ ^= *ip++;
525*7de2b42dSforsyth block_cipher(ds->state.expanded, p, 0);
526*7de2b42dSforsyth memmove(ds->state.ivec, p, 8);
527*7de2b42dSforsyth }
528*7de2b42dSforsyth } else {
529*7de2b42dSforsyth for(ep = p + f->n; p < ep; ){
530*7de2b42dSforsyth memmove(tmp, p, 8);
531*7de2b42dSforsyth block_cipher(ds->state.expanded, p, 1);
532*7de2b42dSforsyth p2 = tmp;
533*7de2b42dSforsyth ip = ds->state.ivec;
534*7de2b42dSforsyth for(eip = ip+8; ip < eip; ){
535*7de2b42dSforsyth *p++ ^= *ip;
536*7de2b42dSforsyth *ip++ = *p2++;
537*7de2b42dSforsyth }
538*7de2b42dSforsyth }
539*7de2b42dSforsyth }
540*7de2b42dSforsyth }
541*7de2b42dSforsyth
542*7de2b42dSforsyth void
Crypt_ideasetup(void * fp)543*7de2b42dSforsyth Crypt_ideasetup(void *fp)
544*7de2b42dSforsyth {
545*7de2b42dSforsyth F_Crypt_ideasetup *f;
546*7de2b42dSforsyth Heap *h;
547*7de2b42dSforsyth XIDEAstate *is;
548*7de2b42dSforsyth uchar *ivec;
549*7de2b42dSforsyth void *v;
550*7de2b42dSforsyth
551*7de2b42dSforsyth f = fp;
552*7de2b42dSforsyth v = *f->ret;
553*7de2b42dSforsyth *f->ret = H;
554*7de2b42dSforsyth destroy(v);
555*7de2b42dSforsyth
556*7de2b42dSforsyth if(f->key == H)
557*7de2b42dSforsyth error(exNilref);
558*7de2b42dSforsyth if(f->key->len < 16)
559*7de2b42dSforsyth error(exBadKey);
560*7de2b42dSforsyth if(f->ivec != H){
561*7de2b42dSforsyth if(f->ivec->len < 8)
562*7de2b42dSforsyth error(exBadIvec);
563*7de2b42dSforsyth ivec = f->ivec->data;
564*7de2b42dSforsyth }else
565*7de2b42dSforsyth ivec = nil;
566*7de2b42dSforsyth
567*7de2b42dSforsyth h = heap(TIDEAstate);
568*7de2b42dSforsyth is = H2D(XIDEAstate*, h);
569*7de2b42dSforsyth
570*7de2b42dSforsyth setupIDEAstate(&is->state, f->key->data, ivec);
571*7de2b42dSforsyth
572*7de2b42dSforsyth *f->ret = (Crypt_IDEAstate*)is;
573*7de2b42dSforsyth }
574*7de2b42dSforsyth
575*7de2b42dSforsyth void
Crypt_ideaecb(void * fp)576*7de2b42dSforsyth Crypt_ideaecb(void *fp)
577*7de2b42dSforsyth {
578*7de2b42dSforsyth F_Crypt_ideaecb *f;
579*7de2b42dSforsyth XIDEAstate *is;
580*7de2b42dSforsyth int i;
581*7de2b42dSforsyth uchar *p;
582*7de2b42dSforsyth
583*7de2b42dSforsyth f = fp;
584*7de2b42dSforsyth
585*7de2b42dSforsyth if(f->buf == H)
586*7de2b42dSforsyth return;
587*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
588*7de2b42dSforsyth error(exBounds);
589*7de2b42dSforsyth if(f->n & 7)
590*7de2b42dSforsyth error(exBadBsize);
591*7de2b42dSforsyth
592*7de2b42dSforsyth is = checktype(f->state, TIDEAstate, exBadState, 0);
593*7de2b42dSforsyth p = f->buf->data;
594*7de2b42dSforsyth
595*7de2b42dSforsyth for(i = 8; i <= f->n; i += 8, p += 8)
596*7de2b42dSforsyth idea_cipher(is->state.edkey, p, f->direction);
597*7de2b42dSforsyth }
598*7de2b42dSforsyth
599*7de2b42dSforsyth void
Crypt_ideacbc(void * fp)600*7de2b42dSforsyth Crypt_ideacbc(void *fp)
601*7de2b42dSforsyth {
602*7de2b42dSforsyth F_Crypt_ideacbc *f;
603*7de2b42dSforsyth XIDEAstate *is;
604*7de2b42dSforsyth uchar *p, *ep, *ip, *p2, *eip;
605*7de2b42dSforsyth uchar tmp[8];
606*7de2b42dSforsyth
607*7de2b42dSforsyth f = fp;
608*7de2b42dSforsyth
609*7de2b42dSforsyth if(f->buf == H)
610*7de2b42dSforsyth return;
611*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
612*7de2b42dSforsyth error(exBounds);
613*7de2b42dSforsyth if(f->n & 7)
614*7de2b42dSforsyth error(exBadBsize);
615*7de2b42dSforsyth
616*7de2b42dSforsyth is = checktype(f->state, TIDEAstate, exBadState, 0);
617*7de2b42dSforsyth p = f->buf->data;
618*7de2b42dSforsyth
619*7de2b42dSforsyth if(f->direction == 0){
620*7de2b42dSforsyth for(ep = p + f->n; p < ep; p += 8){
621*7de2b42dSforsyth p2 = p;
622*7de2b42dSforsyth ip = is->state.ivec;
623*7de2b42dSforsyth for(eip = ip+8; ip < eip; )
624*7de2b42dSforsyth *p2++ ^= *ip++;
625*7de2b42dSforsyth idea_cipher(is->state.edkey, p, 0);
626*7de2b42dSforsyth memmove(is->state.ivec, p, 8);
627*7de2b42dSforsyth }
628*7de2b42dSforsyth } else {
629*7de2b42dSforsyth for(ep = p + f->n; p < ep; ){
630*7de2b42dSforsyth memmove(tmp, p, 8);
631*7de2b42dSforsyth idea_cipher(is->state.edkey, p, 1);
632*7de2b42dSforsyth p2 = tmp;
633*7de2b42dSforsyth ip = is->state.ivec;
634*7de2b42dSforsyth for(eip = ip+8; ip < eip; ){
635*7de2b42dSforsyth *p++ ^= *ip;
636*7de2b42dSforsyth *ip++ = *p2++;
637*7de2b42dSforsyth }
638*7de2b42dSforsyth }
639*7de2b42dSforsyth }
640*7de2b42dSforsyth }
641*7de2b42dSforsyth
642*7de2b42dSforsyth void
Crypt_aessetup(void * fp)643*7de2b42dSforsyth Crypt_aessetup(void *fp)
644*7de2b42dSforsyth {
645*7de2b42dSforsyth F_Crypt_aessetup *f;
646*7de2b42dSforsyth Heap *h;
647*7de2b42dSforsyth XAESstate *is;
648*7de2b42dSforsyth uchar *ivec;
649*7de2b42dSforsyth void *v;
650*7de2b42dSforsyth
651*7de2b42dSforsyth f = fp;
652*7de2b42dSforsyth v = *f->ret;
653*7de2b42dSforsyth *f->ret = H;
654*7de2b42dSforsyth destroy(v);
655*7de2b42dSforsyth
656*7de2b42dSforsyth if(f->key == H)
657*7de2b42dSforsyth error(exNilref);
658*7de2b42dSforsyth if(f->key->len != 16 && f->key->len != 24 && f->key->len != 32)
659*7de2b42dSforsyth error(exBadKey);
660*7de2b42dSforsyth if(f->ivec != H){
661*7de2b42dSforsyth if(f->ivec->len < AESbsize)
662*7de2b42dSforsyth error(exBadIvec);
663*7de2b42dSforsyth ivec = f->ivec->data;
664*7de2b42dSforsyth }else
665*7de2b42dSforsyth ivec = nil;
666*7de2b42dSforsyth
667*7de2b42dSforsyth h = heap(TAESstate);
668*7de2b42dSforsyth is = H2D(XAESstate*, h);
669*7de2b42dSforsyth
670*7de2b42dSforsyth setupAESstate(&is->state, f->key->data, f->key->len, ivec);
671*7de2b42dSforsyth
672*7de2b42dSforsyth *f->ret = (Crypt_AESstate*)is;
673*7de2b42dSforsyth }
674*7de2b42dSforsyth
675*7de2b42dSforsyth void
Crypt_aescbc(void * fp)676*7de2b42dSforsyth Crypt_aescbc(void *fp)
677*7de2b42dSforsyth {
678*7de2b42dSforsyth F_Crypt_aescbc *f;
679*7de2b42dSforsyth XAESstate *is;
680*7de2b42dSforsyth uchar *p;
681*7de2b42dSforsyth
682*7de2b42dSforsyth f = fp;
683*7de2b42dSforsyth
684*7de2b42dSforsyth if(f->buf == H)
685*7de2b42dSforsyth return;
686*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
687*7de2b42dSforsyth error(exBounds);
688*7de2b42dSforsyth
689*7de2b42dSforsyth is = checktype(f->state, TAESstate, exBadState, 0);
690*7de2b42dSforsyth p = f->buf->data;
691*7de2b42dSforsyth
692*7de2b42dSforsyth if(f->direction == 0)
693*7de2b42dSforsyth aesCBCencrypt(p, f->n, &is->state);
694*7de2b42dSforsyth else
695*7de2b42dSforsyth aesCBCdecrypt(p, f->n, &is->state);
696*7de2b42dSforsyth }
697*7de2b42dSforsyth
698*7de2b42dSforsyth void
Crypt_blowfishsetup(void * fp)699*7de2b42dSforsyth Crypt_blowfishsetup(void *fp)
700*7de2b42dSforsyth {
701*7de2b42dSforsyth F_Crypt_blowfishsetup *f;
702*7de2b42dSforsyth Heap *h;
703*7de2b42dSforsyth XBFstate *is;
704*7de2b42dSforsyth uchar *ivec;
705*7de2b42dSforsyth void *v;
706*7de2b42dSforsyth
707*7de2b42dSforsyth f = fp;
708*7de2b42dSforsyth v = *f->ret;
709*7de2b42dSforsyth *f->ret = H;
710*7de2b42dSforsyth destroy(v);
711*7de2b42dSforsyth
712*7de2b42dSforsyth if(f->key == H)
713*7de2b42dSforsyth error(exNilref);
714*7de2b42dSforsyth if(f->key->len <= 0)
715*7de2b42dSforsyth error(exBadKey);
716*7de2b42dSforsyth if(f->ivec != H){
717*7de2b42dSforsyth if(f->ivec->len != BFbsize)
718*7de2b42dSforsyth error(exBadIvec);
719*7de2b42dSforsyth ivec = f->ivec->data;
720*7de2b42dSforsyth }else
721*7de2b42dSforsyth ivec = nil;
722*7de2b42dSforsyth
723*7de2b42dSforsyth h = heap(TBFstate);
724*7de2b42dSforsyth is = H2D(XBFstate*, h);
725*7de2b42dSforsyth
726*7de2b42dSforsyth setupBFstate(&is->state, f->key->data, f->key->len, ivec);
727*7de2b42dSforsyth
728*7de2b42dSforsyth *f->ret = (Crypt_BFstate*)is;
729*7de2b42dSforsyth }
730*7de2b42dSforsyth
731*7de2b42dSforsyth void
Crypt_blowfishcbc(void * fp)732*7de2b42dSforsyth Crypt_blowfishcbc(void *fp)
733*7de2b42dSforsyth {
734*7de2b42dSforsyth F_Crypt_blowfishcbc *f;
735*7de2b42dSforsyth XBFstate *is;
736*7de2b42dSforsyth uchar *p;
737*7de2b42dSforsyth
738*7de2b42dSforsyth f = fp;
739*7de2b42dSforsyth
740*7de2b42dSforsyth if(f->state == H)
741*7de2b42dSforsyth return;
742*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
743*7de2b42dSforsyth error(exBounds);
744*7de2b42dSforsyth if(f->n & 7)
745*7de2b42dSforsyth error(exBadBsize);
746*7de2b42dSforsyth
747*7de2b42dSforsyth is = checktype(f->state, TBFstate, exBadState, 0);
748*7de2b42dSforsyth p = f->buf->data;
749*7de2b42dSforsyth
750*7de2b42dSforsyth if(f->direction == 0)
751*7de2b42dSforsyth bfCBCencrypt(p, f->n, &is->state);
752*7de2b42dSforsyth else
753*7de2b42dSforsyth bfCBCdecrypt(p, f->n, &is->state);
754*7de2b42dSforsyth }
755*7de2b42dSforsyth
756*7de2b42dSforsyth void
Crypt_rc4setup(void * fp)757*7de2b42dSforsyth Crypt_rc4setup(void *fp)
758*7de2b42dSforsyth {
759*7de2b42dSforsyth F_Crypt_rc4setup *f;
760*7de2b42dSforsyth Heap *h;
761*7de2b42dSforsyth XRC4state *is;
762*7de2b42dSforsyth void *v;
763*7de2b42dSforsyth
764*7de2b42dSforsyth f = fp;
765*7de2b42dSforsyth v = *f->ret;
766*7de2b42dSforsyth *f->ret = H;
767*7de2b42dSforsyth destroy(v);
768*7de2b42dSforsyth
769*7de2b42dSforsyth if(f->seed == H)
770*7de2b42dSforsyth error(exNilref);
771*7de2b42dSforsyth
772*7de2b42dSforsyth h = heap(TRC4state);
773*7de2b42dSforsyth is = H2D(XRC4state*, h);
774*7de2b42dSforsyth
775*7de2b42dSforsyth setupRC4state(&is->state, f->seed->data, f->seed->len);
776*7de2b42dSforsyth
777*7de2b42dSforsyth *f->ret = (Crypt_RC4state*)is;
778*7de2b42dSforsyth }
779*7de2b42dSforsyth
780*7de2b42dSforsyth void
Crypt_rc4(void * fp)781*7de2b42dSforsyth Crypt_rc4(void *fp)
782*7de2b42dSforsyth {
783*7de2b42dSforsyth F_Crypt_rc4 *f;
784*7de2b42dSforsyth XRC4state *is;
785*7de2b42dSforsyth uchar *p;
786*7de2b42dSforsyth
787*7de2b42dSforsyth f = fp;
788*7de2b42dSforsyth if(f->buf == H)
789*7de2b42dSforsyth return;
790*7de2b42dSforsyth if(f->n < 0 || f->n > f->buf->len)
791*7de2b42dSforsyth error(exBounds);
792*7de2b42dSforsyth is = checktype(f->state, TRC4state, exBadState, 0);
793*7de2b42dSforsyth p = f->buf->data;
794*7de2b42dSforsyth rc4(&is->state, p, f->n);
795*7de2b42dSforsyth }
796*7de2b42dSforsyth
797*7de2b42dSforsyth void
Crypt_rc4skip(void * fp)798*7de2b42dSforsyth Crypt_rc4skip(void *fp)
799*7de2b42dSforsyth {
800*7de2b42dSforsyth F_Crypt_rc4skip *f;
801*7de2b42dSforsyth XRC4state *is;
802*7de2b42dSforsyth
803*7de2b42dSforsyth f = fp;
804*7de2b42dSforsyth is = checktype(f->state, TRC4state, exBadState, 0);
805*7de2b42dSforsyth rc4skip(&is->state, f->n);
806*7de2b42dSforsyth }
807*7de2b42dSforsyth
808*7de2b42dSforsyth void
Crypt_rc4back(void * fp)809*7de2b42dSforsyth Crypt_rc4back(void *fp)
810*7de2b42dSforsyth {
811*7de2b42dSforsyth F_Crypt_rc4back *f;
812*7de2b42dSforsyth XRC4state *is;
813*7de2b42dSforsyth
814*7de2b42dSforsyth f = fp;
815*7de2b42dSforsyth is = checktype(f->state, TRC4state, exBadState, 0);
816*7de2b42dSforsyth rc4back(&is->state, f->n);
817*7de2b42dSforsyth }
818*7de2b42dSforsyth
819*7de2b42dSforsyth /*
820*7de2b42dSforsyth * public/secret keys, signing and verifying
821*7de2b42dSforsyth */
822*7de2b42dSforsyth
823*7de2b42dSforsyth /*
824*7de2b42dSforsyth * DSA
825*7de2b42dSforsyth */
826*7de2b42dSforsyth
827*7de2b42dSforsyth static void
dsapk2pub(DSApub * p,Crypt_PK * pk)828*7de2b42dSforsyth dsapk2pub(DSApub* p, Crypt_PK* pk)
829*7de2b42dSforsyth {
830*7de2b42dSforsyth if(pk == H)
831*7de2b42dSforsyth error(exNilref);
832*7de2b42dSforsyth if(pk->pick != Crypt_PK_DSA)
833*7de2b42dSforsyth error(exType);
834*7de2b42dSforsyth p->p = MPX(pk->u.DSA.p);
835*7de2b42dSforsyth p->q = MPX(pk->u.DSA.q);
836*7de2b42dSforsyth p->alpha = MPX(pk->u.DSA.alpha);
837*7de2b42dSforsyth p->key = MPX(pk->u.DSA.key);
838*7de2b42dSforsyth }
839*7de2b42dSforsyth
840*7de2b42dSforsyth static void
dsask2priv(DSApriv * p,Crypt_SK * sk)841*7de2b42dSforsyth dsask2priv(DSApriv* p, Crypt_SK* sk)
842*7de2b42dSforsyth {
843*7de2b42dSforsyth if(sk == H)
844*7de2b42dSforsyth error(exNilref);
845*7de2b42dSforsyth if(sk->pick != Crypt_SK_DSA)
846*7de2b42dSforsyth error(exType);
847*7de2b42dSforsyth dsapk2pub(&p->pub, sk->u.DSA.pk);
848*7de2b42dSforsyth p->secret = MPX(sk->u.DSA.secret);
849*7de2b42dSforsyth }
850*7de2b42dSforsyth
851*7de2b42dSforsyth static void
dsapriv2sk(Crypt_SK * sk,DSApriv * p)852*7de2b42dSforsyth dsapriv2sk(Crypt_SK* sk, DSApriv* p)
853*7de2b42dSforsyth {
854*7de2b42dSforsyth Crypt_PK *pk;
855*7de2b42dSforsyth
856*7de2b42dSforsyth pk = sk->u.DSA.pk;
857*7de2b42dSforsyth pk->u.DSA.p = ipcopymp(p->pub.p);
858*7de2b42dSforsyth pk->u.DSA.q = ipcopymp(p->pub.q);
859*7de2b42dSforsyth pk->u.DSA.alpha = ipcopymp(p->pub.alpha);
860*7de2b42dSforsyth pk->u.DSA.key = ipcopymp(p->pub.key);
861*7de2b42dSforsyth sk->u.DSA.secret = ipcopymp(p->secret);
862*7de2b42dSforsyth }
863*7de2b42dSforsyth
864*7de2b42dSforsyth static void
dsaxgen(Crypt_SK * sk,DSApub * oldpk)865*7de2b42dSforsyth dsaxgen(Crypt_SK* sk, DSApub* oldpk)
866*7de2b42dSforsyth {
867*7de2b42dSforsyth DSApriv *p;
868*7de2b42dSforsyth
869*7de2b42dSforsyth release();
870*7de2b42dSforsyth p = dsagen(oldpk);
871*7de2b42dSforsyth acquire();
872*7de2b42dSforsyth dsapriv2sk(sk, p);
873*7de2b42dSforsyth dsaprivfree(p);
874*7de2b42dSforsyth }
875*7de2b42dSforsyth
876*7de2b42dSforsyth void
Crypt_dsagen(void * fp)877*7de2b42dSforsyth Crypt_dsagen(void *fp)
878*7de2b42dSforsyth {
879*7de2b42dSforsyth F_Crypt_dsagen *f;
880*7de2b42dSforsyth Crypt_SK *sk;
881*7de2b42dSforsyth DSApub pub, *oldpk;
882*7de2b42dSforsyth void *v;
883*7de2b42dSforsyth
884*7de2b42dSforsyth f = fp;
885*7de2b42dSforsyth v = *f->ret;
886*7de2b42dSforsyth *f->ret = H;
887*7de2b42dSforsyth destroy(v);
888*7de2b42dSforsyth
889*7de2b42dSforsyth sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
890*7de2b42dSforsyth oldpk = nil;
891*7de2b42dSforsyth if(f->oldpk != H && f->oldpk->pick == Crypt_PK_DSA){
892*7de2b42dSforsyth dsapk2pub(&pub, f->oldpk);
893*7de2b42dSforsyth oldpk = &pub;
894*7de2b42dSforsyth }
895*7de2b42dSforsyth dsaxgen(sk, oldpk);
896*7de2b42dSforsyth }
897*7de2b42dSforsyth
898*7de2b42dSforsyth /*
899*7de2b42dSforsyth * Elgamal
900*7de2b42dSforsyth */
901*7de2b42dSforsyth
902*7de2b42dSforsyth static void
egpk2pub(EGpub * p,Crypt_PK * pk)903*7de2b42dSforsyth egpk2pub(EGpub* p, Crypt_PK* pk)
904*7de2b42dSforsyth {
905*7de2b42dSforsyth if(pk == H)
906*7de2b42dSforsyth error(exNilref);
907*7de2b42dSforsyth if(pk->pick != Crypt_PK_Elgamal)
908*7de2b42dSforsyth error(exType);
909*7de2b42dSforsyth p->p = MPX(pk->u.Elgamal.p);
910*7de2b42dSforsyth p->alpha = MPX(pk->u.Elgamal.alpha);
911*7de2b42dSforsyth p->key = MPX(pk->u.Elgamal.key);
912*7de2b42dSforsyth }
913*7de2b42dSforsyth
914*7de2b42dSforsyth static void
egsk2priv(EGpriv * p,Crypt_SK * sk)915*7de2b42dSforsyth egsk2priv(EGpriv* p, Crypt_SK* sk)
916*7de2b42dSforsyth {
917*7de2b42dSforsyth if(sk == H)
918*7de2b42dSforsyth error(exNilref);
919*7de2b42dSforsyth if(sk->pick != Crypt_SK_Elgamal)
920*7de2b42dSforsyth error(exType);
921*7de2b42dSforsyth egpk2pub(&p->pub, sk->u.Elgamal.pk);
922*7de2b42dSforsyth p->secret = MPX(sk->u.Elgamal.secret);
923*7de2b42dSforsyth }
924*7de2b42dSforsyth
925*7de2b42dSforsyth static void
egpriv2sk(Crypt_SK * sk,EGpriv * p)926*7de2b42dSforsyth egpriv2sk(Crypt_SK* sk, EGpriv* p)
927*7de2b42dSforsyth {
928*7de2b42dSforsyth Crypt_PK* pk;
929*7de2b42dSforsyth
930*7de2b42dSforsyth pk = sk->u.Elgamal.pk;
931*7de2b42dSforsyth pk->u.Elgamal.p = ipcopymp(p->pub.p);
932*7de2b42dSforsyth pk->u.Elgamal.alpha = ipcopymp(p->pub.alpha);
933*7de2b42dSforsyth pk->u.Elgamal.key = ipcopymp(p->pub.key);
934*7de2b42dSforsyth sk->u.Elgamal.secret = ipcopymp(p->secret);
935*7de2b42dSforsyth }
936*7de2b42dSforsyth
937*7de2b42dSforsyth static void
egxgen(Crypt_SK * sk,int nlen,int nrep)938*7de2b42dSforsyth egxgen(Crypt_SK* sk, int nlen, int nrep)
939*7de2b42dSforsyth {
940*7de2b42dSforsyth EGpriv *p;
941*7de2b42dSforsyth
942*7de2b42dSforsyth release();
943*7de2b42dSforsyth for(;;){
944*7de2b42dSforsyth p = eggen(nlen, nrep);
945*7de2b42dSforsyth if(mpsignif(p->pub.p) == nlen)
946*7de2b42dSforsyth break;
947*7de2b42dSforsyth egprivfree(p);
948*7de2b42dSforsyth }
949*7de2b42dSforsyth acquire();
950*7de2b42dSforsyth egpriv2sk(sk, p);
951*7de2b42dSforsyth egprivfree(p);
952*7de2b42dSforsyth }
953*7de2b42dSforsyth
954*7de2b42dSforsyth
955*7de2b42dSforsyth void
Crypt_eggen(void * fp)956*7de2b42dSforsyth Crypt_eggen(void *fp)
957*7de2b42dSforsyth {
958*7de2b42dSforsyth F_Crypt_eggen *f;
959*7de2b42dSforsyth Crypt_SK *sk;
960*7de2b42dSforsyth void *v;
961*7de2b42dSforsyth
962*7de2b42dSforsyth f = fp;
963*7de2b42dSforsyth v = *f->ret;
964*7de2b42dSforsyth *f->ret = H;
965*7de2b42dSforsyth destroy(v);
966*7de2b42dSforsyth
967*7de2b42dSforsyth sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
968*7de2b42dSforsyth egxgen(sk, f->nlen, f->nrep);
969*7de2b42dSforsyth }
970*7de2b42dSforsyth
971*7de2b42dSforsyth /*
972*7de2b42dSforsyth * RSA
973*7de2b42dSforsyth */
974*7de2b42dSforsyth
975*7de2b42dSforsyth static void
rsapk2pub(RSApub * p,Crypt_PK * pk)976*7de2b42dSforsyth rsapk2pub(RSApub* p, Crypt_PK* pk)
977*7de2b42dSforsyth {
978*7de2b42dSforsyth if(pk == H)
979*7de2b42dSforsyth error(exNilref);
980*7de2b42dSforsyth if(pk->pick != Crypt_PK_RSA)
981*7de2b42dSforsyth error(exType);
982*7de2b42dSforsyth p->n = MPX(pk->u.RSA.n);
983*7de2b42dSforsyth p->ek = MPX(pk->u.RSA.ek);
984*7de2b42dSforsyth }
985*7de2b42dSforsyth
986*7de2b42dSforsyth static void
rsask2priv(RSApriv * p,Crypt_SK * sk)987*7de2b42dSforsyth rsask2priv(RSApriv* p, Crypt_SK* sk)
988*7de2b42dSforsyth {
989*7de2b42dSforsyth if(sk == H)
990*7de2b42dSforsyth error(exNilref);
991*7de2b42dSforsyth if(sk->pick != Crypt_SK_RSA)
992*7de2b42dSforsyth error(exType);
993*7de2b42dSforsyth rsapk2pub(&p->pub, sk->u.RSA.pk);
994*7de2b42dSforsyth p->dk = MPX(sk->u.RSA.dk);
995*7de2b42dSforsyth p->p = MPX(sk->u.RSA.p);
996*7de2b42dSforsyth p->q = MPX(sk->u.RSA.q);
997*7de2b42dSforsyth p->kp = MPX(sk->u.RSA.kp);
998*7de2b42dSforsyth p->kq = MPX(sk->u.RSA.kq);
999*7de2b42dSforsyth p->c2 = MPX(sk->u.RSA.c2);
1000*7de2b42dSforsyth }
1001*7de2b42dSforsyth
1002*7de2b42dSforsyth static void
rsapriv2sk(Crypt_SK * sk,RSApriv * p)1003*7de2b42dSforsyth rsapriv2sk(Crypt_SK* sk, RSApriv* p)
1004*7de2b42dSforsyth {
1005*7de2b42dSforsyth Crypt_PK *pk;
1006*7de2b42dSforsyth
1007*7de2b42dSforsyth pk = sk->u.RSA.pk;
1008*7de2b42dSforsyth pk->u.RSA.n = ipcopymp(p->pub.n);
1009*7de2b42dSforsyth pk->u.RSA.ek = ipcopymp(p->pub.ek);
1010*7de2b42dSforsyth sk->u.RSA.dk = ipcopymp(p->dk);
1011*7de2b42dSforsyth sk->u.RSA.p = ipcopymp(p->p);
1012*7de2b42dSforsyth sk->u.RSA.q = ipcopymp(p->q);
1013*7de2b42dSforsyth sk->u.RSA.kp = ipcopymp(p->kp);
1014*7de2b42dSforsyth sk->u.RSA.kq = ipcopymp(p->kq);
1015*7de2b42dSforsyth sk->u.RSA.c2 = ipcopymp(p->c2);
1016*7de2b42dSforsyth }
1017*7de2b42dSforsyth
1018*7de2b42dSforsyth static void
rsaxgen(Crypt_SK * sk,int nlen,int elen,int nrep)1019*7de2b42dSforsyth rsaxgen(Crypt_SK *sk, int nlen, int elen, int nrep)
1020*7de2b42dSforsyth {
1021*7de2b42dSforsyth RSApriv *p;
1022*7de2b42dSforsyth
1023*7de2b42dSforsyth release();
1024*7de2b42dSforsyth for(;;){
1025*7de2b42dSforsyth p = rsagen(nlen, elen, nrep);
1026*7de2b42dSforsyth if(mpsignif(p->pub.n) == nlen)
1027*7de2b42dSforsyth break;
1028*7de2b42dSforsyth rsaprivfree(p);
1029*7de2b42dSforsyth }
1030*7de2b42dSforsyth acquire();
1031*7de2b42dSforsyth rsapriv2sk(sk, p);
1032*7de2b42dSforsyth rsaprivfree(p);
1033*7de2b42dSforsyth }
1034*7de2b42dSforsyth
1035*7de2b42dSforsyth void
Crypt_rsagen(void * fp)1036*7de2b42dSforsyth Crypt_rsagen(void *fp)
1037*7de2b42dSforsyth {
1038*7de2b42dSforsyth F_Crypt_rsagen *f;
1039*7de2b42dSforsyth Crypt_SK *sk;
1040*7de2b42dSforsyth void *v;
1041*7de2b42dSforsyth
1042*7de2b42dSforsyth f = fp;
1043*7de2b42dSforsyth v = *f->ret;
1044*7de2b42dSforsyth *f->ret = H;
1045*7de2b42dSforsyth destroy(v);
1046*7de2b42dSforsyth
1047*7de2b42dSforsyth sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1048*7de2b42dSforsyth rsaxgen(sk, f->nlen, f->elen, f->nrep);
1049*7de2b42dSforsyth }
1050*7de2b42dSforsyth
1051*7de2b42dSforsyth void
Crypt_rsafill(void * fp)1052*7de2b42dSforsyth Crypt_rsafill(void *fp)
1053*7de2b42dSforsyth {
1054*7de2b42dSforsyth F_Crypt_rsafill *f;
1055*7de2b42dSforsyth Crypt_SK *sk;
1056*7de2b42dSforsyth RSApriv *p;
1057*7de2b42dSforsyth void *v;
1058*7de2b42dSforsyth
1059*7de2b42dSforsyth f = fp;
1060*7de2b42dSforsyth v = *f->ret;
1061*7de2b42dSforsyth *f->ret = H;
1062*7de2b42dSforsyth destroy(v);
1063*7de2b42dSforsyth
1064*7de2b42dSforsyth sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1065*7de2b42dSforsyth release();
1066*7de2b42dSforsyth p = rsafill(MPX(f->n), MPX(f->ek), MPX(f->dk),
1067*7de2b42dSforsyth MPX(f->p), MPX(f->q));
1068*7de2b42dSforsyth acquire();
1069*7de2b42dSforsyth if(p == nil) {
1070*7de2b42dSforsyth *f->ret = H;
1071*7de2b42dSforsyth destroy(sk);
1072*7de2b42dSforsyth }else{
1073*7de2b42dSforsyth rsapriv2sk(sk, p);
1074*7de2b42dSforsyth rsaprivfree(p);
1075*7de2b42dSforsyth }
1076*7de2b42dSforsyth }
1077*7de2b42dSforsyth
1078*7de2b42dSforsyth void
Crypt_rsaencrypt(void * fp)1079*7de2b42dSforsyth Crypt_rsaencrypt(void *fp)
1080*7de2b42dSforsyth {
1081*7de2b42dSforsyth F_Crypt_rsaencrypt *f;
1082*7de2b42dSforsyth RSApub p;
1083*7de2b42dSforsyth mpint *m, *o;
1084*7de2b42dSforsyth void *v;
1085*7de2b42dSforsyth
1086*7de2b42dSforsyth f = fp;
1087*7de2b42dSforsyth v = *f->ret;
1088*7de2b42dSforsyth *f->ret = H;
1089*7de2b42dSforsyth destroy(v);
1090*7de2b42dSforsyth
1091*7de2b42dSforsyth rsapk2pub(&p, f->k);
1092*7de2b42dSforsyth m = MPX(f->m);
1093*7de2b42dSforsyth release();
1094*7de2b42dSforsyth o = rsaencrypt(&p, m, nil);
1095*7de2b42dSforsyth acquire();
1096*7de2b42dSforsyth *f->ret = newIPint(o);
1097*7de2b42dSforsyth }
1098*7de2b42dSforsyth
1099*7de2b42dSforsyth void
Crypt_rsadecrypt(void * fp)1100*7de2b42dSforsyth Crypt_rsadecrypt(void *fp)
1101*7de2b42dSforsyth {
1102*7de2b42dSforsyth F_Crypt_rsadecrypt *f;
1103*7de2b42dSforsyth RSApriv p;
1104*7de2b42dSforsyth mpint *m, *o;
1105*7de2b42dSforsyth void *v;
1106*7de2b42dSforsyth
1107*7de2b42dSforsyth f = fp;
1108*7de2b42dSforsyth v = *f->ret;
1109*7de2b42dSforsyth *f->ret = H;
1110*7de2b42dSforsyth destroy(v);
1111*7de2b42dSforsyth
1112*7de2b42dSforsyth rsask2priv(&p, f->k);
1113*7de2b42dSforsyth m = MPX(f->m);
1114*7de2b42dSforsyth release();
1115*7de2b42dSforsyth o = rsadecrypt(&p, m, nil);
1116*7de2b42dSforsyth acquire();
1117*7de2b42dSforsyth *f->ret = newIPint(o);
1118*7de2b42dSforsyth }
1119*7de2b42dSforsyth
1120*7de2b42dSforsyth /*
1121*7de2b42dSforsyth * generic key functions
1122*7de2b42dSforsyth */
1123*7de2b42dSforsyth
1124*7de2b42dSforsyth void
Crypt_genSK(void * fp)1125*7de2b42dSforsyth Crypt_genSK(void *fp)
1126*7de2b42dSforsyth {
1127*7de2b42dSforsyth F_Crypt_genSK *f;
1128*7de2b42dSforsyth Crypt_SK *sk;
1129*7de2b42dSforsyth char *sa;
1130*7de2b42dSforsyth void *v;
1131*7de2b42dSforsyth
1132*7de2b42dSforsyth f = fp;
1133*7de2b42dSforsyth v = *f->ret;
1134*7de2b42dSforsyth *f->ret = H;
1135*7de2b42dSforsyth destroy(v);
1136*7de2b42dSforsyth
1137*7de2b42dSforsyth sa = string2c(f->algname);
1138*7de2b42dSforsyth if(strcmp(sa, "rsa") == 0){
1139*7de2b42dSforsyth sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1140*7de2b42dSforsyth rsaxgen(sk, f->length, 6, 0);
1141*7de2b42dSforsyth }else if(strcmp(sa, "dsa") == 0){
1142*7de2b42dSforsyth sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
1143*7de2b42dSforsyth dsaxgen(sk, nil);
1144*7de2b42dSforsyth }else if(strcmp(sa, "elgamal") == 0){
1145*7de2b42dSforsyth sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
1146*7de2b42dSforsyth egxgen(sk, f->length, 0);
1147*7de2b42dSforsyth }
1148*7de2b42dSforsyth /* genSK returns nil for unknown algorithm */
1149*7de2b42dSforsyth }
1150*7de2b42dSforsyth
1151*7de2b42dSforsyth void
Crypt_genSKfromPK(void * fp)1152*7de2b42dSforsyth Crypt_genSKfromPK(void *fp)
1153*7de2b42dSforsyth {
1154*7de2b42dSforsyth F_Crypt_genSKfromPK *f;
1155*7de2b42dSforsyth Crypt_SK *sk;
1156*7de2b42dSforsyth void *v;
1157*7de2b42dSforsyth
1158*7de2b42dSforsyth f = fp;
1159*7de2b42dSforsyth v = *f->ret;
1160*7de2b42dSforsyth *f->ret = H;
1161*7de2b42dSforsyth destroy(v);
1162*7de2b42dSforsyth
1163*7de2b42dSforsyth if(f->pk == H)
1164*7de2b42dSforsyth error(exNilref);
1165*7de2b42dSforsyth switch(f->pk->pick){
1166*7de2b42dSforsyth case Crypt_PK_RSA: {
1167*7de2b42dSforsyth RSApub p;
1168*7de2b42dSforsyth
1169*7de2b42dSforsyth rsapk2pub(&p, f->pk);
1170*7de2b42dSforsyth sk = newSK(f->ret, TSKrsa, Crypt_SK_RSA);
1171*7de2b42dSforsyth rsaxgen(sk, mpsignif(p.n), mpsignif(p.ek), 0);
1172*7de2b42dSforsyth }
1173*7de2b42dSforsyth break;
1174*7de2b42dSforsyth case Crypt_PK_Elgamal: {
1175*7de2b42dSforsyth EGpub p;
1176*7de2b42dSforsyth
1177*7de2b42dSforsyth egpk2pub(&p, f->pk);
1178*7de2b42dSforsyth sk = newSK(f->ret, TSKeg, Crypt_SK_Elgamal);
1179*7de2b42dSforsyth egxgen(sk, mpsignif(p.p), 0);
1180*7de2b42dSforsyth }
1181*7de2b42dSforsyth break;
1182*7de2b42dSforsyth case Crypt_PK_DSA: {
1183*7de2b42dSforsyth DSApub p;
1184*7de2b42dSforsyth
1185*7de2b42dSforsyth dsapk2pub(&p, f->pk);
1186*7de2b42dSforsyth sk = newSK(f->ret, TSKdsa, Crypt_SK_DSA);
1187*7de2b42dSforsyth dsaxgen(sk, &p);
1188*7de2b42dSforsyth }
1189*7de2b42dSforsyth break;
1190*7de2b42dSforsyth default:
1191*7de2b42dSforsyth /* shouldn't happen */
1192*7de2b42dSforsyth error(exType);
1193*7de2b42dSforsyth }
1194*7de2b42dSforsyth }
1195*7de2b42dSforsyth
1196*7de2b42dSforsyth void
Crypt_sktopk(void * fp)1197*7de2b42dSforsyth Crypt_sktopk(void *fp)
1198*7de2b42dSforsyth {
1199*7de2b42dSforsyth F_Crypt_sktopk *f;
1200*7de2b42dSforsyth Crypt_PK *pk;
1201*7de2b42dSforsyth void *v;
1202*7de2b42dSforsyth
1203*7de2b42dSforsyth f = fp;
1204*7de2b42dSforsyth v = *f->ret;
1205*7de2b42dSforsyth *f->ret = H;
1206*7de2b42dSforsyth destroy(v);
1207*7de2b42dSforsyth if(f->sk == H)
1208*7de2b42dSforsyth error(exNilref);
1209*7de2b42dSforsyth switch(f->sk->pick){
1210*7de2b42dSforsyth case Crypt_PK_RSA:
1211*7de2b42dSforsyth pk = f->sk->u.RSA.pk;
1212*7de2b42dSforsyth break;
1213*7de2b42dSforsyth case Crypt_PK_Elgamal:
1214*7de2b42dSforsyth pk = f->sk->u.Elgamal.pk;
1215*7de2b42dSforsyth break;
1216*7de2b42dSforsyth case Crypt_PK_DSA:
1217*7de2b42dSforsyth pk = f->sk->u.DSA.pk;
1218*7de2b42dSforsyth break;
1219*7de2b42dSforsyth default:
1220*7de2b42dSforsyth pk = H;
1221*7de2b42dSforsyth error(exType);
1222*7de2b42dSforsyth }
1223*7de2b42dSforsyth if(pk == H)
1224*7de2b42dSforsyth return;
1225*7de2b42dSforsyth D2H(pk)->ref++;
1226*7de2b42dSforsyth *f->ret = pk;
1227*7de2b42dSforsyth }
1228*7de2b42dSforsyth
1229*7de2b42dSforsyth void
Crypt_sign(void * fp)1230*7de2b42dSforsyth Crypt_sign(void *fp)
1231*7de2b42dSforsyth {
1232*7de2b42dSforsyth F_Crypt_sign *f;
1233*7de2b42dSforsyth Crypt_PKsig *sig;
1234*7de2b42dSforsyth mpint *m;
1235*7de2b42dSforsyth void *v;
1236*7de2b42dSforsyth
1237*7de2b42dSforsyth f = fp;
1238*7de2b42dSforsyth v = *f->ret;
1239*7de2b42dSforsyth *f->ret = H;
1240*7de2b42dSforsyth destroy(v);
1241*7de2b42dSforsyth
1242*7de2b42dSforsyth if(f->m == H || f->sk == H)
1243*7de2b42dSforsyth error(exNilref);
1244*7de2b42dSforsyth m = MPX(f->m);
1245*7de2b42dSforsyth switch(f->sk->pick){
1246*7de2b42dSforsyth case Crypt_SK_RSA: {
1247*7de2b42dSforsyth RSApriv p;
1248*7de2b42dSforsyth mpint *s;
1249*7de2b42dSforsyth
1250*7de2b42dSforsyth rsask2priv(&p, f->sk);
1251*7de2b42dSforsyth release();
1252*7de2b42dSforsyth s = rsadecrypt(&p, m, nil);
1253*7de2b42dSforsyth acquire();
1254*7de2b42dSforsyth sig = newPKsig(TPKsigrsa, Crypt_PKsig_RSA);
1255*7de2b42dSforsyth sig->u.RSA.n = newIPint(s);
1256*7de2b42dSforsyth }
1257*7de2b42dSforsyth break;
1258*7de2b42dSforsyth case Crypt_SK_Elgamal: {
1259*7de2b42dSforsyth EGpriv p;
1260*7de2b42dSforsyth EGsig *s;
1261*7de2b42dSforsyth
1262*7de2b42dSforsyth egsk2priv(&p, f->sk);
1263*7de2b42dSforsyth release();
1264*7de2b42dSforsyth s = egsign(&p, m);
1265*7de2b42dSforsyth acquire();
1266*7de2b42dSforsyth sig = newPKsig(TPKsigeg, Crypt_PKsig_Elgamal);
1267*7de2b42dSforsyth sig->u.Elgamal.r = ipcopymp(s->r);
1268*7de2b42dSforsyth sig->u.Elgamal.s = ipcopymp(s->s);
1269*7de2b42dSforsyth egsigfree(s);
1270*7de2b42dSforsyth }
1271*7de2b42dSforsyth break;
1272*7de2b42dSforsyth case Crypt_SK_DSA: {
1273*7de2b42dSforsyth DSApriv p;
1274*7de2b42dSforsyth DSAsig *s;
1275*7de2b42dSforsyth
1276*7de2b42dSforsyth dsask2priv(&p, f->sk);
1277*7de2b42dSforsyth m = MPX(f->m);
1278*7de2b42dSforsyth release();
1279*7de2b42dSforsyth s = dsasign(&p, m);
1280*7de2b42dSforsyth acquire();
1281*7de2b42dSforsyth sig = newPKsig(TPKsigdsa, Crypt_PKsig_DSA);
1282*7de2b42dSforsyth sig->u.DSA.r = ipcopymp(s->r);
1283*7de2b42dSforsyth sig->u.DSA.s = ipcopymp(s->s);
1284*7de2b42dSforsyth dsasigfree(s);
1285*7de2b42dSforsyth }
1286*7de2b42dSforsyth break;
1287*7de2b42dSforsyth default:
1288*7de2b42dSforsyth sig = H;
1289*7de2b42dSforsyth error(exType);
1290*7de2b42dSforsyth }
1291*7de2b42dSforsyth *f->ret = sig;
1292*7de2b42dSforsyth }
1293*7de2b42dSforsyth
1294*7de2b42dSforsyth void
Crypt_verify(void * fp)1295*7de2b42dSforsyth Crypt_verify(void *fp)
1296*7de2b42dSforsyth {
1297*7de2b42dSforsyth F_Crypt_verify *f;
1298*7de2b42dSforsyth mpint *m;
1299*7de2b42dSforsyth
1300*7de2b42dSforsyth f = fp;
1301*7de2b42dSforsyth *f->ret = 0;
1302*7de2b42dSforsyth if(f->sig == H || f->pk == H)
1303*7de2b42dSforsyth error(exNilref);
1304*7de2b42dSforsyth if(f->sig->pick != f->pk->pick)
1305*7de2b42dSforsyth return; /* key type and signature mismatch, doesn't validate */
1306*7de2b42dSforsyth m = MPX(f->m);
1307*7de2b42dSforsyth switch(f->pk->pick){
1308*7de2b42dSforsyth case Crypt_PK_RSA: {
1309*7de2b42dSforsyth RSApub p;
1310*7de2b42dSforsyth mpint *sig, *t;
1311*7de2b42dSforsyth
1312*7de2b42dSforsyth rsapk2pub(&p, f->pk);
1313*7de2b42dSforsyth sig = MPX(f->sig->u.RSA.n);
1314*7de2b42dSforsyth release();
1315*7de2b42dSforsyth t = rsaencrypt(&p, sig, nil);
1316*7de2b42dSforsyth *f->ret = mpcmp(t, m) == 0;
1317*7de2b42dSforsyth mpfree(t);
1318*7de2b42dSforsyth acquire();
1319*7de2b42dSforsyth }
1320*7de2b42dSforsyth break;
1321*7de2b42dSforsyth case Crypt_PK_Elgamal: {
1322*7de2b42dSforsyth EGpub p;
1323*7de2b42dSforsyth EGsig sig;
1324*7de2b42dSforsyth
1325*7de2b42dSforsyth egpk2pub(&p, f->pk);
1326*7de2b42dSforsyth sig.r = MPX(f->sig->u.Elgamal.r);
1327*7de2b42dSforsyth sig.s = MPX(f->sig->u.Elgamal.s);
1328*7de2b42dSforsyth release();
1329*7de2b42dSforsyth *f->ret = egverify(&p, &sig, m) == 0;
1330*7de2b42dSforsyth acquire();
1331*7de2b42dSforsyth }
1332*7de2b42dSforsyth break;
1333*7de2b42dSforsyth case Crypt_PK_DSA: {
1334*7de2b42dSforsyth DSApub p;
1335*7de2b42dSforsyth DSAsig sig;
1336*7de2b42dSforsyth
1337*7de2b42dSforsyth dsapk2pub(&p, f->pk);
1338*7de2b42dSforsyth sig.r = MPX(f->sig->u.DSA.r);
1339*7de2b42dSforsyth sig.s = MPX(f->sig->u.DSA.s);
1340*7de2b42dSforsyth release();
1341*7de2b42dSforsyth *f->ret = dsaverify(&p, &sig, m) == 0;
1342*7de2b42dSforsyth acquire();
1343*7de2b42dSforsyth }
1344*7de2b42dSforsyth break;
1345*7de2b42dSforsyth default:
1346*7de2b42dSforsyth error(exType);
1347*7de2b42dSforsyth }
1348*7de2b42dSforsyth }
1349