devtls: TLS1.1 explicit iv support
using nrand() to fill the explicit iv, which isnt great but better than no iv.
This commit is contained in:
parent
76f21ca715
commit
74d1f67b05
1 changed files with 45 additions and 16 deletions
|
@ -11,22 +11,22 @@
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
|
|
||||||
typedef struct OneWay OneWay;
|
typedef struct OneWay OneWay;
|
||||||
typedef struct Secret Secret;
|
typedef struct Secret Secret;
|
||||||
typedef struct TlsRec TlsRec;
|
typedef struct TlsRec TlsRec;
|
||||||
typedef struct TlsErrs TlsErrs;
|
typedef struct TlsErrs TlsErrs;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Statlen= 1024, /* max. length of status or stats message */
|
Statlen= 1024, /* max. length of status or stats message */
|
||||||
/* buffer limits */
|
/* 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,
|
MaxCipherRecLen = MaxRecLen + 2048,
|
||||||
RecHdrLen = 5,
|
RecHdrLen = 5,
|
||||||
MaxMacLen = SHA1dlen,
|
MaxMacLen = SHA1dlen,
|
||||||
|
|
||||||
/* protocol versions we can accept */
|
/* protocol versions we can accept */
|
||||||
TLSVersion = 0x0301,
|
SSL3Version = 0x0300,
|
||||||
SSL3Version = 0x0300,
|
TLS10Version = 0x0301,
|
||||||
ProtocolVersion = 0x0301, /* maximum version we speak */
|
TLS11Version = 0x0302,
|
||||||
MinProtoVersion = 0x0300, /* limits on version we accept */
|
MinProtoVersion = 0x0300, /* limits on version we accept */
|
||||||
MaxProtoVersion = 0x03ff,
|
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
|
/* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
|
||||||
should look alike, including timing of the response. */
|
should look alike, including timing of the response. */
|
||||||
unpad_len = (*in->sec->dec)(in->sec, p, len);
|
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)
|
if(unpad_len >= in->sec->maclen)
|
||||||
len = unpad_len - in->sec->maclen;
|
len = unpad_len - in->sec->maclen;
|
||||||
|
|
||||||
if(tr->debug) pprint("decrypted %d\n", unpad_len);
|
if(tr->debug) pprint("decrypted %d\n", unpad_len);
|
||||||
if(tr->debug) pdump(unpad_len, p, "decrypted:");
|
if(tr->debug) pdump(unpad_len, p, "decrypted:");
|
||||||
|
|
||||||
|
@ -815,7 +827,8 @@ if(tr->debug) pdump(unpad_len, p, "decrypted:");
|
||||||
rcvError(tr, EBadRecordMac, "short record mac");
|
rcvError(tr, EBadRecordMac, "short record mac");
|
||||||
if(memcmp(hmac, p+len, in->sec->maclen) != 0)
|
if(memcmp(hmac, p+len, in->sec->maclen) != 0)
|
||||||
rcvError(tr, EBadRecordMac, "record mac mismatch");
|
rcvError(tr, EBadRecordMac, "record mac mismatch");
|
||||||
b->wp = b->rp + len;
|
b->rp = p;
|
||||||
|
b->wp = p+len;
|
||||||
}
|
}
|
||||||
qunlock(&in->seclock);
|
qunlock(&in->seclock);
|
||||||
poperror();
|
poperror();
|
||||||
|
@ -1210,6 +1223,13 @@ tlsread(Chan *c, void *a, long n, vlong off)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
randfill(uchar *buf, int len)
|
||||||
|
{
|
||||||
|
while(len-- > 0)
|
||||||
|
*buf++ = nrand(256);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write a block in tls records
|
* write a block in tls records
|
||||||
*/
|
*/
|
||||||
|
@ -1220,7 +1240,7 @@ tlsrecwrite(TlsRec *tr, int type, Block *b)
|
||||||
Block *nb;
|
Block *nb;
|
||||||
uchar *p, seq[8];
|
uchar *p, seq[8];
|
||||||
OneWay *volatile out;
|
OneWay *volatile out;
|
||||||
int n, maclen, pad, ok;
|
int n, ivlen, maclen, pad, ok;
|
||||||
|
|
||||||
out = &tr->out;
|
out = &tr->out;
|
||||||
bb = b;
|
bb = b;
|
||||||
|
@ -1253,21 +1273,24 @@ if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
|
||||||
qlock(&out->seclock);
|
qlock(&out->seclock);
|
||||||
maclen = 0;
|
maclen = 0;
|
||||||
pad = 0;
|
pad = 0;
|
||||||
|
ivlen = 0;
|
||||||
if(out->sec != nil){
|
if(out->sec != nil){
|
||||||
maclen = out->sec->maclen;
|
maclen = out->sec->maclen;
|
||||||
pad = maclen + out->sec->block;
|
pad = maclen + out->sec->block;
|
||||||
|
if(tr->version >= TLS11Version)
|
||||||
|
ivlen = out->sec->block;
|
||||||
}
|
}
|
||||||
n = BLEN(bb);
|
n = BLEN(bb);
|
||||||
if(n > MaxRecLen){
|
if(n > MaxRecLen){
|
||||||
n = MaxRecLen;
|
n = MaxRecLen;
|
||||||
nb = allocb(n + pad + RecHdrLen);
|
nb = allocb(RecHdrLen + ivlen + n + pad);
|
||||||
memmove(nb->wp + RecHdrLen, bb->rp, n);
|
memmove(nb->wp + RecHdrLen + ivlen, bb->rp, n);
|
||||||
bb->rp += n;
|
bb->rp += n;
|
||||||
}else{
|
}else{
|
||||||
/*
|
/*
|
||||||
* carefully reuse bb so it will get freed if we're out of memory
|
* 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)
|
if(pad)
|
||||||
nb = padblock(bb, -pad);
|
nb = padblock(bb, -pad);
|
||||||
else
|
else
|
||||||
|
@ -1283,9 +1306,15 @@ if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
|
||||||
if(out->sec != nil){
|
if(out->sec != nil){
|
||||||
put64(seq, out->seq);
|
put64(seq, out->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;
|
n += maclen;
|
||||||
|
|
||||||
|
/* explicit iv */
|
||||||
|
if(ivlen > 0){
|
||||||
|
randfill(p + RecHdrLen, ivlen);
|
||||||
|
n += ivlen;
|
||||||
|
}
|
||||||
|
|
||||||
/* encrypt */
|
/* encrypt */
|
||||||
n = (*out->sec->enc)(out->sec, p + RecHdrLen, n);
|
n = (*out->sec->enc)(out->sec, p + RecHdrLen, n);
|
||||||
nb->wp = p + RecHdrLen + n;
|
nb->wp = p + RecHdrLen + n;
|
||||||
|
@ -1563,12 +1592,12 @@ tlswrite(Chan *c, void *a, long n, vlong off)
|
||||||
if(tr->verset)
|
if(tr->verset)
|
||||||
error("version already set");
|
error("version already set");
|
||||||
m = strtol(cb->f[1], nil, 0);
|
m = strtol(cb->f[1], nil, 0);
|
||||||
|
if(m < MinProtoVersion || m > MaxProtoVersion)
|
||||||
|
error("unsupported version");
|
||||||
if(m == SSL3Version)
|
if(m == SSL3Version)
|
||||||
tr->packMac = sslPackMac;
|
tr->packMac = sslPackMac;
|
||||||
else if(m == TLSVersion)
|
|
||||||
tr->packMac = tlsPackMac;
|
|
||||||
else
|
else
|
||||||
error("unsupported version");
|
tr->packMac = tlsPackMac;
|
||||||
tr->verset = 1;
|
tr->verset = 1;
|
||||||
tr->version = m;
|
tr->version = m;
|
||||||
}else if(strcmp(cb->f[0], "secret") == 0){
|
}else if(strcmp(cb->f[0], "secret") == 0){
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue