shithub: riscv

Download patch

ref: 74d1f67b0547aa1b32648a2364f3cd6739d3e60a
parent: 76f21ca715d99dd533053c8465ecdd16915fadbc
author: cinap_lenrek <[email protected]>
date: Sat Aug 15 13:50:44 EDT 2015

devtls: TLS1.1 explicit iv support

using nrand() to fill the explicit iv, which isnt great but better
than no iv.

--- a/sys/src/9/port/devtls.c
+++ b/sys/src/9/port/devtls.c
@@ -11,7 +11,7 @@
 #include	<libsec.h>
 
 typedef struct OneWay	OneWay;
-typedef struct Secret		Secret;
+typedef struct Secret	Secret;
 typedef struct TlsRec	TlsRec;
 typedef struct TlsErrs	TlsErrs;
 
@@ -18,15 +18,15 @@
 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 @@
 		/* 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:");
 
@@ -815,7 +827,8 @@
 			rcvError(tr, EBadRecordMac, "short record mac");
 		if(memcmp(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 @@
 	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 @@
 	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 @@
 		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(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 @@
 		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){