diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-01-06 03:09:00 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-01-06 03:09:00 +0100 |
commit | 2dae1ed53a73d81bfb86778793a6bda265d5140d (patch) | |
tree | e037c4a663fc9d17906cc2045c488232ac223ece /sys/src/libauthsrv/authpak.c | |
parent | e064752dd476b7a2f76567f8cc15f9c2645e5d3d (diff) |
auth: release dp9ik implementation and reentrant factotum
Diffstat (limited to 'sys/src/libauthsrv/authpak.c')
-rw-r--r-- | sys/src/libauthsrv/authpak.c | 214 |
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; +} |