X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fport%2Fdevtls.c;h=ad6750a36ca922d177dfbe207c1f9a623233a806;hb=6b402b83cffc97015345dab1c27c35afe64bb3db;hp=4cb30b371aee620fc89008c46caec9a780635845;hpb=5c6357de8bda7c5fe0a7fa4ab31b365a9ae8e6fb;p=plan9front.git diff --git a/sys/src/9/port/devtls.c b/sys/src/9/port/devtls.c index 4cb30b371..ad6750a36 100644 --- a/sys/src/9/port/devtls.c +++ b/sys/src/9/port/devtls.c @@ -11,22 +11,22 @@ #include typedef struct OneWay OneWay; -typedef struct Secret Secret; +typedef struct Secret Secret; typedef struct TlsRec TlsRec; typedef struct TlsErrs TlsErrs; enum { Statlen= 1024, /* max. length of status or stats message */ /* buffer limits */ - MaxRecLen = 1<<14, /* max payload length of a record layer message */ + MaxRecLen = 1<<14, /* max payload length of a record layer message */ MaxCipherRecLen = MaxRecLen + 2048, - RecHdrLen = 5, - MaxMacLen = SHA1dlen, + RecHdrLen = 5, + MaxMacLen = SHA1dlen, /* protocol versions we can accept */ - TLSVersion = 0x0301, - SSL3Version = 0x0300, - ProtocolVersion = 0x0301, /* maximum version we speak */ + SSL3Version = 0x0300, + TLS10Version = 0x0301, + TLS11Version = 0x0302, MinProtoVersion = 0x0300, /* limits on version we accept */ MaxProtoVersion = 0x03ff, @@ -801,8 +801,20 @@ if(tr->debug) pprint("consumed unprocessed %d\n", len); /* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here should look alike, including timing of the response. */ unpad_len = (*in->sec->dec)(in->sec, p, len); + + /* excplicit iv */ + if(tr->version >= TLS11Version){ + len -= in->sec->block; + if(len < 0) + rcvError(tr, EDecodeError, "runt record message"); + + unpad_len -= in->sec->block; + p += in->sec->block; + } + if(unpad_len >= in->sec->maclen) len = unpad_len - in->sec->maclen; + if(tr->debug) pprint("decrypted %d\n", unpad_len); if(tr->debug) pdump(unpad_len, p, "decrypted:"); @@ -813,9 +825,10 @@ if(tr->debug) pdump(unpad_len, p, "decrypted:"); (*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac); if(unpad_len < in->sec->maclen) rcvError(tr, EBadRecordMac, "short record mac"); - if(memcmp(hmac, p+len, in->sec->maclen) != 0) + if(constcmp(hmac, p+len, in->sec->maclen) != 0) rcvError(tr, EBadRecordMac, "record mac mismatch"); - b->wp = b->rp + len; + b->rp = p; + b->wp = p+len; } qunlock(&in->seclock); poperror(); @@ -1210,6 +1223,13 @@ tlsread(Chan *c, void *a, long n, vlong off) return n; } +static void +randfill(uchar *buf, int len) +{ + while(len-- > 0) + *buf++ = nrand(256); +} + /* * write a block in tls records */ @@ -1220,7 +1240,7 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) Block *nb; uchar *p, seq[8]; OneWay *volatile out; - int n, maclen, pad, ok; + int n, ivlen, maclen, pad, ok; out = &tr->out; bb = b; @@ -1253,21 +1273,24 @@ if(tr->debug)pdump(BLEN(b), b->rp, "sent:"); qlock(&out->seclock); maclen = 0; pad = 0; + ivlen = 0; if(out->sec != nil){ maclen = out->sec->maclen; pad = maclen + out->sec->block; + if(tr->version >= TLS11Version) + ivlen = out->sec->block; } n = BLEN(bb); if(n > MaxRecLen){ n = MaxRecLen; - nb = allocb(n + pad + RecHdrLen); - memmove(nb->wp + RecHdrLen, bb->rp, n); + nb = allocb(RecHdrLen + ivlen + n + pad); + memmove(nb->wp + RecHdrLen + ivlen, bb->rp, n); bb->rp += n; }else{ /* * carefully reuse bb so it will get freed if we're out of memory */ - bb = padblock(bb, RecHdrLen); + bb = padblock(bb, RecHdrLen + ivlen); if(pad) nb = padblock(bb, -pad); else @@ -1283,9 +1306,15 @@ if(tr->debug)pdump(BLEN(b), b->rp, "sent:"); if(out->sec != nil){ put64(seq, out->seq); out->seq++; - (*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, p + RecHdrLen + n); + (*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen + ivlen, n, p + RecHdrLen + ivlen + n); n += maclen; + /* explicit iv */ + if(ivlen > 0){ + randfill(p + RecHdrLen, ivlen); + n += ivlen; + } + /* encrypt */ n = (*out->sec->enc)(out->sec, p + RecHdrLen, n); nb->wp = p + RecHdrLen + n; @@ -1563,12 +1592,12 @@ tlswrite(Chan *c, void *a, long n, vlong off) if(tr->verset) error("version already set"); m = strtol(cb->f[1], nil, 0); + if(m < MinProtoVersion || m > MaxProtoVersion) + error("unsupported version"); if(m == SSL3Version) tr->packMac = sslPackMac; - else if(m == TLSVersion) - tr->packMac = tlsPackMac; else - error("unsupported version"); + tr->packMac = tlsPackMac; tr->verset = 1; tr->version = m; }else if(strcmp(cb->f[0], "secret") == 0){