summaryrefslogtreecommitdiff
path: root/sys/src/libauthsrv/authpak.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-01-06 03:09:00 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2016-01-06 03:09:00 +0100
commit2dae1ed53a73d81bfb86778793a6bda265d5140d (patch)
treee037c4a663fc9d17906cc2045c488232ac223ece /sys/src/libauthsrv/authpak.c
parente064752dd476b7a2f76567f8cc15f9c2645e5d3d (diff)
auth: release dp9ik implementation and reentrant factotum
Diffstat (limited to 'sys/src/libauthsrv/authpak.c')
-rw-r--r--sys/src/libauthsrv/authpak.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/sys/src/libauthsrv/authpak.c b/sys/src/libauthsrv/authpak.c
new file mode 100644
index 000000000..50f7ee6d0
--- /dev/null
+++ b/sys/src/libauthsrv/authpak.c
@@ -0,0 +1,214 @@
+#include <u.h>
+#include <libc.h>
+#include <mp.h>
+#include <libsec.h>
+#include <authsrv.h>
+
+#include "msqrt.mpc"
+#include "decaf.mpc"
+#include "edwards.mpc"
+#include "elligator2.mpc"
+#include "spake2ee.mpc"
+#include "ed448.mpc"
+
+typedef struct PAKcurve PAKcurve;
+struct PAKcurve
+{
+ Lock;
+ mpint *P;
+ mpint *A;
+ mpint *D;
+ mpint *X;
+ mpint *Y;
+};
+
+static PAKcurve*
+authpak_curve(void)
+{
+ static PAKcurve a;
+
+ lock(&a);
+ if(a.P == nil){
+ a.P = mpnew(0);
+ a.A = mpnew(0);
+ a.D = mpnew(0);
+ a.X = mpnew(0);
+ a.Y = mpnew(0);
+ ed448_curve(a.P, a.A, a.D, a.X, a.Y);
+ a.P = mpfield(a.P);
+ }
+ unlock(&a);
+ return &a;
+}
+
+void
+authpak_hash(Authkey *k, char *u)
+{
+ static char info[] = "Plan 9 AuthPAK hash";
+ uchar *bp, salt[SHA2_256dlen], h[2*PAKSLEN];
+ mpint *H, *PX,*PY,*PZ,*PT;
+ PAKcurve *c;
+
+ H = mpnew(0);
+ PX = mpnew(0);
+ PY = mpnew(0);
+ PZ = mpnew(0);
+ PT = mpnew(0);
+
+ sha2_256((uchar*)u, strlen(u), salt, nil);
+
+ hkdf_x( salt, SHA2_256dlen,
+ (uchar*)info, sizeof(info)-1,
+ k->aes, AESKEYLEN,
+ h, sizeof(h),
+ hmac_sha2_256, SHA2_256dlen);
+
+ c = authpak_curve();
+
+ betomp(h + 0*PAKSLEN, PAKSLEN, H); /* HM */
+ spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT); /* PM */
+
+ bp = k->pakhash;
+ mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PT, bp, PAKSLEN), bp += PAKSLEN;
+
+ betomp(h + 1*PAKSLEN, PAKSLEN, H); /* HN */
+ spake2ee_h2P(c->P,c->A,c->D, H, PX,PY,PZ,PT); /* PN */
+
+ mptober(PX, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PY, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PZ, bp, PAKSLEN), bp += PAKSLEN;
+ mptober(PT, bp, PAKSLEN);
+
+ mpfree(PX);
+ mpfree(PY);
+ mpfree(PZ);
+ mpfree(PT);
+ mpfree(H);
+}
+
+void
+authpak_new(PAKpriv *p, Authkey *k, uchar y[PAKYLEN], int isclient)
+{
+ mpint *PX,*PY,*PZ,*PT, *X, *Y;
+ PAKcurve *c;
+ uchar *bp;
+
+ memset(p, 0, sizeof(PAKpriv));
+ p->isclient = isclient != 0;
+
+ X = mpnew(0);
+ Y = mpnew(0);
+
+ PX = mpnew(0);
+ PY = mpnew(0);
+ PZ = mpnew(0);
+ PT = mpnew(0);
+
+ PX->flags |= MPtimesafe;
+ PY->flags |= MPtimesafe;
+ PZ->flags |= MPtimesafe;
+ PT->flags |= MPtimesafe;
+
+ bp = k->pakhash + PAKPLEN*(p->isclient == 0);
+ betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PT);
+
+ c = authpak_curve();
+
+ X->flags |= MPtimesafe;
+ mpnrand(c->P, genrandom, X);
+
+ spake2ee_1(c->P,c->A,c->D, X, c->X,c->Y, PX,PY,PZ,PT, Y);
+
+ mptober(X, p->x, PAKXLEN);
+ mptober(Y, p->y, PAKYLEN);
+
+ memmove(y, p->y, PAKYLEN);
+
+ mpfree(PX);
+ mpfree(PY);
+ mpfree(PZ);
+ mpfree(PT);
+
+ mpfree(X);
+ mpfree(Y);
+}
+
+int
+authpak_finish(PAKpriv *p, Authkey *k, uchar y[PAKYLEN])
+{
+ static char info[] = "Plan 9 AuthPAK key";
+ uchar *bp, z[PAKSLEN], salt[SHA2_256dlen];
+ mpint *PX,*PY,*PZ,*PT, *X, *Y, *Z, *ok;
+ DigestState *s;
+ PAKcurve *c;
+ int ret;
+
+ X = mpnew(0);
+ Y = mpnew(0);
+ Z = mpnew(0);
+ ok = mpnew(0);
+
+ PX = mpnew(0);
+ PY = mpnew(0);
+ PZ = mpnew(0);
+ PT = mpnew(0);
+
+ PX->flags |= MPtimesafe;
+ PY->flags |= MPtimesafe;
+ PZ->flags |= MPtimesafe;
+ PT->flags |= MPtimesafe;
+
+ bp = k->pakhash + PAKPLEN*(p->isclient != 0);
+ betomp(bp, PAKSLEN, PX), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PY), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PZ), bp += PAKSLEN;
+ betomp(bp, PAKSLEN, PT);
+
+ Z->flags |= MPtimesafe;
+ X->flags |= MPtimesafe;
+ betomp(p->x, PAKXLEN, X);
+
+ betomp(y, PAKYLEN, Y);
+
+ c = authpak_curve();
+ spake2ee_2(c->P,c->A,c->D, PX,PY,PZ,PT, X, Y, ok, Z);
+
+ if(mpcmp(ok, mpzero) == 0){
+ ret = -1;
+ goto out;
+ }
+
+ mptober(Z, z, sizeof(z));
+
+ s = sha2_256(p->isclient ? p->y : y, PAKYLEN, nil, nil);
+ sha2_256(p->isclient ? y : p->y, PAKYLEN, salt, s);
+
+ hkdf_x( salt, SHA2_256dlen,
+ (uchar*)info, sizeof(info)-1,
+ z, sizeof(z),
+ k->pakkey, PAKKEYLEN,
+ hmac_sha2_256, SHA2_256dlen);
+
+ ret = 0;
+out:
+ memset(z, 0, sizeof(z));
+ memset(p, 0, sizeof(PAKpriv));
+
+ mpfree(PX);
+ mpfree(PY);
+ mpfree(PZ);
+ mpfree(PT);
+
+ mpfree(X);
+ mpfree(Y);
+ mpfree(Z);
+ mpfree(ok);
+
+ return ret;
+}