diff options
author | mischief <mischief@offblast.org> | 2015-08-25 02:07:46 -0700 |
---|---|---|
committer | mischief <mischief@offblast.org> | 2015-08-25 02:07:46 -0700 |
commit | 6b402b83cffc97015345dab1c27c35afe64bb3db (patch) | |
tree | b525f9443564682c46f8c36af6a4d238bd39a756 /sys/src/libsec | |
parent | dbe0a995f03f26ea2b6859d21df3bd67856d672d (diff) |
import E script from bell labs
Diffstat (limited to 'sys/src/libsec')
-rw-r--r-- | sys/src/libsec/port/const.c | 18 | ||||
-rw-r--r-- | sys/src/libsec/port/ecc.c | 125 | ||||
-rw-r--r-- | sys/src/libsec/port/mkfile | 1 | ||||
-rw-r--r-- | sys/src/libsec/port/thumb.c | 2 | ||||
-rw-r--r-- | sys/src/libsec/port/tlshand.c | 84 | ||||
-rw-r--r-- | sys/src/libsec/port/x509.c | 2 |
6 files changed, 162 insertions, 70 deletions
diff --git a/sys/src/libsec/port/const.c b/sys/src/libsec/port/const.c new file mode 100644 index 000000000..0cf400178 --- /dev/null +++ b/sys/src/libsec/port/const.c @@ -0,0 +1,18 @@ +#include <u.h> + +/* + * returns 0 if the the len bytes in x are equal to len bytes in y, + * otherwise returns -1. + */ +int +constcmp(uchar *x, uchar *y, int len) +{ + uint z; + int i; + + for(z = 0, i = 0; i < len; i++) { + z |= x[i] ^ y[i]; + } + + return (1 & ((z - 1) >> 8)) - 1; +} diff --git a/sys/src/libsec/port/ecc.c b/sys/src/libsec/port/ecc.c index 261eebdd1..09dd92858 100644 --- a/sys/src/libsec/port/ecc.c +++ b/sys/src/libsec/port/ecc.c @@ -3,6 +3,76 @@ #include <libsec.h> #include <ctype.h> +ECdomain * +ecnamedcurve(int id) +{ + ECdomain *dom; + dom = malloc(sizeof(ECdomain)); + if(dom == nil) + return nil; + + switch(id) { + default: + free(dom); + return nil; + case Secp256r1: + dom->p = strtomp("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", nil, 16, nil); + dom->a = strtomp("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", nil, 16, nil); + dom->b = strtomp("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", nil, 16, nil); + dom->G = strtoec(dom, "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", nil, nil); + dom->n = strtomp("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", nil, 16, nil); + dom->h = uitomp(1, nil); + break; + } + + if(dom->p == nil || dom->a == nil || dom->b == nil || dom->G == nil || dom->n == nil || dom->h == nil) { + ecfreedomain(dom); + return nil; + } + + return dom; +} + +void +ecfreepoint(ECpoint *pt) +{ + if(pt != nil) { + mpfree(pt->x); + mpfree(pt->y); + } + + free(pt); +} + +void +ecfreepriv(ECpriv *priv) +{ + if(priv != nil) { + mpfree(priv->x); + mpfree(priv->y); + mpfree(priv->d); + } + + free(priv); +} + +void +ecfreedomain(ECdomain *dom) +{ + if(dom != nil) { + mpfree(dom->p); + mpfree(dom->a); + mpfree(dom->b); + if(dom->G != nil) { + ecfreepoint(dom->G); + } + mpfree(dom->n); + mpfree(dom->h); + } + + free(dom); +} + void ecassign(ECdomain *, ECpoint *a, ECpoint *b) { @@ -329,6 +399,54 @@ mpsqrt(mpint *n, mpint *p, mpint *r) return 1; } +// converts the bytes in buf to an ECpoint x y pair. +// the domain is used to determine the number of bytes in x and y in the buffer. +ECpoint* +betoec(ECdomain *dom, uchar *buf, int blen, ECpoint *ret) +{ + int allocd, bytelen; + + allocd = 0; + bytelen = (mpsignif(dom->p)+7) >> 3; + + // sanity check arguments + if(dom == nil || buf == nil) + return nil; + + // check if input is too short for two mpints + if(blen != 1+2*bytelen) + return nil; + + // check that point is in uncompressed format + if(buf[0] != 4) + return nil; + + if(ret == nil) { + // allocate return pointer and mpints + allocd = 1; + ret = mallocz(sizeof(*ret), 1); + if(ret == nil) + return nil; + ret->x = mpnew(0); + ret->y = mpnew(0); + } + + // uncompressed form + if(betomp(buf+1, bytelen, ret->x) == nil) + goto err; + if(betomp(buf+1+bytelen, bytelen, ret->y) == nil) + goto err; + if(!ecverify(dom, ret)) + goto err; + return ret; + +err: + if(allocd){ + ecfreepoint(ret); + } + return nil; +} + ECpoint* strtoec(ECdomain *dom, char *s, char **rptr, ECpoint *ret) { @@ -382,11 +500,8 @@ strtoec(ECdomain *dom, char *s, char **rptr, ECpoint *ret) err: if(rptr) *rptr = s; - if(allocd){ - mpfree(ret->x); - mpfree(ret->y); - free(ret); - } + if(allocd) + ecfreepoint(ret); return nil; } diff --git a/sys/src/libsec/port/mkfile b/sys/src/libsec/port/mkfile index 60aebe629..91973cb26 100644 --- a/sys/src/libsec/port/mkfile +++ b/sys/src/libsec/port/mkfile @@ -22,6 +22,7 @@ CFILES = des.c desmodes.c desECB.c desCBC.c des3ECB.c des3CBC.c\ ripemd.c\ dh.c\ pbkdf2.c\ + const.c\ ALLOFILES=${CFILES:%.c=%.$O} diff --git a/sys/src/libsec/port/thumb.c b/sys/src/libsec/port/thumb.c index 21c92fe88..8a2e53e97 100644 --- a/sys/src/libsec/port/thumb.c +++ b/sys/src/libsec/port/thumb.c @@ -38,7 +38,7 @@ okThumbprint(uchar *sum, Thumbprint *table) return 0; hd = tablehead(sum, table); for(p = hd->next; p; p = p->next){ - if(memcmp(sum, p->sha1, SHA1dlen) == 0) + if(constcmp(sum, p->sha1, SHA1dlen) == 0) return 1; if(p == hd) break; diff --git a/sys/src/libsec/port/tlshand.c b/sys/src/libsec/port/tlshand.c index 48c281068..8151c60c4 100644 --- a/sys/src/libsec/port/tlshand.c +++ b/sys/src/libsec/port/tlshand.c @@ -854,99 +854,57 @@ ectobytes(int type, ECpoint *p) static Bytes* tlsSecECDHEc(TlsSec *sec, uchar *srandom, int vers, int curve, Bytes *Ys) { - Namedcurve *nc, *enc; Bytes *epm; - ECdomain dom; - ECpoint G, K, Y; - ECpriv Q; + ECdomain *dom; + ECpoint K, *Y; + ECpriv *Q; + + epm = nil; + Y = nil; + Q = nil; if(Ys == nil) return nil; - enc = &namedcurves[nelem(namedcurves)]; - for(nc = namedcurves; nc != enc; nc++) - if(nc->tlsid == curve) - break; - - if(nc == enc) - return nil; - memmove(sec->srandom, srandom, RandomSize); if(setVers(sec, vers) < 0) return nil; - - epm = nil; - - memset(&dom, 0, sizeof(dom)); - dom.p = strtomp(nc->p, nil, 16, nil); - dom.a = strtomp(nc->a, nil, 16, nil); - dom.b = strtomp(nc->b, nil, 16, nil); - dom.n = strtomp(nc->n, nil, 16, nil); - dom.h = strtomp(nc->h, nil, 16, nil); - memset(&G, 0, sizeof(G)); - G.x = mpnew(0); - G.y = mpnew(0); + dom = ecnamedcurve(curve); + if(dom == nil) + return nil; - memset(&Q, 0, sizeof(Q)); - Q.x = mpnew(0); - Q.y = mpnew(0); - Q.d = mpnew(0); memset(&K, 0, sizeof(K)); K.x = mpnew(0); K.y = mpnew(0); - memset(&Y, 0, sizeof(Y)); - Y.x = mpnew(0); - Y.y = mpnew(0); - - if(dom.p == nil || dom.a == nil || dom.b == nil || dom.n == nil || dom.h == nil) - goto Out; - if(Q.x == nil || Q.y == nil || Q.d == nil) - goto Out; - if(G.x == nil || G.y == nil) - goto Out; if(K.x == nil || K.y == nil) goto Out; - if(Y.x == nil || Y.y == nil) - goto Out; - dom.G = strtoec(&dom, nc->G, nil, &G); - if(dom.G == nil) + Y = betoec(dom, Ys->data, Ys->len, nil); + if(Y == nil) goto Out; - if(bytestoec(&dom, Ys, &Y) == nil) + Q = ecgen(dom, nil); + if(Q == nil) goto Out; - if(ecgen(&dom, &Q) == nil) - goto Out; - - ecmul(&dom, &Y, Q.d, &K); + ecmul(dom, Y, Q->d, &K); setMasterSecret(sec, mptobytes(K.x)); /* 0x04 = uncompressed public key */ - epm = ectobytes(0x04, &Q); + epm = ectobytes(0x04, Q); Out: - mpfree(Y.x); - mpfree(Y.y); + ecfreepriv(Q); + + ecfreepoint(Y); mpfree(K.x); mpfree(K.y); - mpfree(Q.x); - mpfree(Q.y); - mpfree(Q.d); - - mpfree(G.x); - mpfree(G.y); - - mpfree(dom.p); - mpfree(dom.a); - mpfree(dom.b); - mpfree(dom.n); - mpfree(dom.h); + ecfreedomain(dom); return epm; } @@ -1957,7 +1915,7 @@ setVersion(TlsConnection *c, int version) static int finishedMatch(TlsConnection *c, Finished *f) { - return memcmp(f->verify, c->finished.verify, f->n) == 0; + return constcmp(f->verify, c->finished.verify, f->n) == 0; } // free memory associated with TlsConnection struct diff --git a/sys/src/libsec/port/x509.c b/sys/src/libsec/port/x509.c index 4751524c5..a6dc9e5d7 100644 --- a/sys/src/libsec/port/x509.c +++ b/sys/src/libsec/port/x509.c @@ -2212,7 +2212,7 @@ verify_signature(Bytes* signature, RSApub *pk, uchar *edigest, int edigestlen, E err = "bad digest length"; goto end; } - if(memcmp(digest->data, edigest, edigestlen) != 0) + if(constcmp(digest->data, edigest, edigestlen) != 0) err = "digests did not match"; end: |