]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libauthsrv/authpak.c
upas/marshal: fix printinreplyto function
[plan9front.git] / sys / src / libauthsrv / authpak.c
1 #include <u.h>
2 #include <libc.h>
3 #include <mp.h>
4 #include <libsec.h>
5 #include <authsrv.h>
6
7 #include "msqrt.mpc"
8 #include "decaf.mpc"
9 #include "edwards.mpc"
10 #include "elligator2.mpc"
11 #include "spake2ee.mpc"
12 #include "ed448.mpc"
13
14 typedef struct PAKcurve PAKcurve;
15 struct PAKcurve
16 {
17         Lock;
18         mpint   *P;
19         mpint   *A;
20         mpint   *D;
21         mpint   *X;
22         mpint   *Y;
23 };
24
25 static PAKcurve*
26 authpak_curve(void)
27 {
28         static PAKcurve a;
29
30         lock(&a);
31         if(a.P == nil){
32                 a.P = mpnew(0);
33                 a.A = mpnew(0);
34                 a.D = mpnew(0);
35                 a.X = mpnew(0);
36                 a.Y = mpnew(0);
37                 ed448_curve(a.P, a.A, a.D, a.X, a.Y);
38                 a.P = mpfield(a.P);
39         }
40         unlock(&a);
41         return &a;
42 }
43
44 void
45 authpak_hash(Authkey *k, char *u)
46 {
47         static char info[] = "Plan 9 AuthPAK hash";
48         uchar *bp, salt[SHA2_256dlen], h[2*PAKSLEN];
49         mpint *H, *PX,*PY,*PZ,*PT;
50         PAKcurve *c;
51
52         H = mpnew(0);
53         PX = mpnew(0);
54         PY = mpnew(0);
55         PZ = mpnew(0);
56         PT = mpnew(0);
57
58         sha2_256((uchar*)u, strlen(u), salt, nil);
59
60         hkdf_x( salt, SHA2_256dlen,
61                 (uchar*)info, sizeof(info)-1,
62                 k->aes, AESKEYLEN,
63                 h, sizeof(h),
64                 hmac_sha2_256, SHA2_256dlen);
65
66         c = authpak_curve();
67
68         betomp(h + 0*PAKSLEN, PAKSLEN, H);              /* HM */
69         spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT);   /* PM */
70
71         bp = k->pakhash;
72         mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
73         mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
74         mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
75         mptober(PT, bp, PAKSLEN), bp += PAKSLEN;
76
77         betomp(h + 1*PAKSLEN, PAKSLEN, H);              /* HN */
78         spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT);   /* PN */
79
80         mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
81         mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
82         mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
83         mptober(PT, bp, PAKSLEN);
84
85         mpfree(PX);
86         mpfree(PY);
87         mpfree(PZ);
88         mpfree(PT);
89         mpfree(H);
90 }
91
92 void
93 authpak_new(PAKpriv *p, Authkey *k, uchar y[PAKYLEN], int isclient)
94 {
95         mpint *PX,*PY,*PZ,*PT, *X, *Y;
96         PAKcurve *c;
97         uchar *bp;
98
99         memset(p, 0, sizeof(PAKpriv));
100         p->isclient = isclient != 0;
101
102         X = mpnew(0);
103         Y = mpnew(0);
104
105         PX = mpnew(0);
106         PY = mpnew(0);
107         PZ = mpnew(0);
108         PT = mpnew(0);
109
110         PX->flags |= MPtimesafe;
111         PY->flags |= MPtimesafe;
112         PZ->flags |= MPtimesafe;
113         PT->flags |= MPtimesafe;
114
115         bp = k->pakhash + PAKPLEN*(p->isclient == 0);
116         betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
117         betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
118         betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
119         betomp(bp, PAKSLEN, PT);
120
121         c = authpak_curve();
122
123         X->flags |= MPtimesafe;
124         mpnrand(c->P, genrandom, X);
125
126         spake2ee_1(c->P,c->A,c->D, X, c->X,c->Y, PX,PY,PZ,PT, Y);
127
128         mptober(X, p->x, PAKXLEN);
129         mptober(Y, p->y, PAKYLEN);
130
131         memmove(y, p->y, PAKYLEN);
132
133         mpfree(PX);
134         mpfree(PY);
135         mpfree(PZ);
136         mpfree(PT);
137
138         mpfree(X);
139         mpfree(Y);
140 }
141
142 int
143 authpak_finish(PAKpriv *p, Authkey *k, uchar y[PAKYLEN])
144 {
145         static char info[] = "Plan 9 AuthPAK key";
146         uchar *bp, z[PAKSLEN], salt[SHA2_256dlen];
147         mpint *PX,*PY,*PZ,*PT, *X, *Y, *Z, *ok;
148         DigestState *s;
149         PAKcurve *c;
150         int ret;
151
152         X = mpnew(0);
153         Y = mpnew(0);
154         Z = mpnew(0);
155         ok = mpnew(0);
156
157         PX = mpnew(0);
158         PY = mpnew(0);
159         PZ = mpnew(0);
160         PT = mpnew(0);
161
162         PX->flags |= MPtimesafe;
163         PY->flags |= MPtimesafe;
164         PZ->flags |= MPtimesafe;
165         PT->flags |= MPtimesafe;
166
167         bp = k->pakhash + PAKPLEN*(p->isclient != 0);
168         betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
169         betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
170         betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
171         betomp(bp, PAKSLEN, PT);
172
173         Z->flags |= MPtimesafe;
174         X->flags |= MPtimesafe;
175         betomp(p->x, PAKXLEN, X);
176
177         betomp(y, PAKYLEN, Y);
178
179         c = authpak_curve();
180         spake2ee_2(c->P,c->A,c->D, PX,PY,PZ,PT, X, Y, ok, Z);
181
182         if(mpcmp(ok, mpzero) == 0){
183                 ret = -1;
184                 goto out;
185         }
186
187         mptober(Z, z, sizeof(z));
188
189         s = sha2_256(p->isclient ? p->y : y, PAKYLEN, nil, nil);
190         sha2_256(p->isclient ? y : p->y, PAKYLEN, salt, s);
191
192         hkdf_x( salt, SHA2_256dlen,
193                 (uchar*)info, sizeof(info)-1,
194                 z, sizeof(z),
195                 k->pakkey, PAKKEYLEN,
196                 hmac_sha2_256, SHA2_256dlen);
197
198         ret = 0;
199 out:
200         memset(z, 0, sizeof(z));
201         memset(p, 0, sizeof(PAKpriv));
202
203         mpfree(PX);
204         mpfree(PY);
205         mpfree(PZ);
206         mpfree(PT);
207
208         mpfree(X);
209         mpfree(Y);
210         mpfree(Z);
211         mpfree(ok);
212
213         return ret;
214 }