shithub: riscv

Download patch

ref: bdc1b187c45dbaeaa7dadce4d7999d9d550ec78f
parent: a0cc369c15bdd404e1a60b4fd5b3a5156a041f74
parent: 2e23780d2f4f1e3a55a096227a01995d0f0c2e52
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jan 12 15:17:52 EST 2017

merge

--- a/sys/include/ape/libsec.h
+++ b/sys/include/ape/libsec.h
@@ -101,6 +101,7 @@
 	ChachaBsize=	64,
 	ChachaKeylen=	256/8,
 	ChachaIVlen=	96/8,
+	XChachaIVlen=	192/8,
 };
 
 typedef struct Chachastate Chachastate;
@@ -115,6 +116,7 @@
 			u32int	iv[3];
 		};
 	};
+	u32int	xkey[8];
 	int	rounds;
 	int	ivwords;
 };
@@ -125,6 +127,8 @@
 void	chacha_encrypt(uchar*, ulong, Chachastate*);
 void	chacha_encrypt2(uchar*, uchar*, ulong, Chachastate*);
 
+void	hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
+
 void	ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
 int	ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
 
@@ -143,7 +147,7 @@
 struct Salsastate
 {
 	u32int	input[16];
-	u32int	key[8];
+	u32int	xkey[8];
 	int	rounds;
 	int	ivwords;
 };
--- a/sys/include/libsec.h
+++ b/sys/include/libsec.h
@@ -93,6 +93,7 @@
 	ChachaBsize=	64,
 	ChachaKeylen=	256/8,
 	ChachaIVlen=	96/8,
+	XChachaIVlen=	192/8,
 };
 
 typedef struct Chachastate Chachastate;
@@ -107,6 +108,7 @@
 			u32int	iv[3];
 		};
 	};
+	u32int	xkey[8];
 	int	rounds;
 	int	ivwords;
 };
@@ -117,6 +119,8 @@
 void	chacha_encrypt(uchar*, ulong, Chachastate*);
 void	chacha_encrypt2(uchar*, uchar*, ulong, Chachastate*);
 
+void	hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
+
 void	ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
 int	ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
 
@@ -135,7 +139,7 @@
 struct Salsastate
 {
 	u32int	input[16];
-	u32int	key[8];
+	u32int	xkey[8];
 	int	rounds;
 	int	ivwords;
 };
--- a/sys/man/2/chacha
+++ b/sys/man/2/chacha
@@ -1,6 +1,6 @@
 .TH CHACHA 2
 .SH NAME
-setupChachastate, chacha_setblock, chacha_setiv, chacha_encrypt, chacha_encrypt2, ccpoly_encrypt, ccpoly_decrypt \- chacha encryption
+setupChachastate, chacha_setblock, chacha_setiv, chacha_encrypt, chacha_encrypt2, hchacha, ccpoly_encrypt, ccpoly_decrypt \- chacha encryption
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -24,6 +24,9 @@
 void chacha_setiv(Chachastate *s, uchar *iv);
 .PP
 .B
+void hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds);
+.PP
+.B
 void ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs);
 .PP
 .B
@@ -49,8 +52,11 @@
 or nonce of
 .I ivlen
 bytes (can be
-.BR ChachaIVlen =12
-or 8, set to all zeros if the
+.BR ChachaIVlen =12 ,
+.B 8
+or
+.BR XChachaIVlen =24 ;
+set to all zeros if the
 .I iv
 argument is nil),
 and the number of
@@ -93,6 +99,10 @@
 .I Chacha_setiv
 sets the the initialization vector (nonce) to
 .IR iv .
+.PP
+.I Hchacha
+is a key expansion function that takes a 128 or 256-bit key 
+and a 128-bit nonce and produces a new 256-bit key.
 .PP
 .I Ccpoly_encrypt
 and
--- a/sys/src/9/ip/tcp.c
+++ b/sys/src/9/ip/tcp.c
@@ -3282,6 +3282,8 @@
 static char*
 tcpctl(Conv* c, char** f, int n)
 {
+	if(n == 1 && strcmp(f[0], "close") == 0)
+		return tcpclose(c), nil;
 	if(n == 1 && strcmp(f[0], "hangup") == 0)
 		return tcphangup(c);
 	if(n >= 1 && strcmp(f[0], "keepalive") == 0)
--- a/sys/src/9/port/cache.c
+++ b/sys/src/9/port/cache.c
@@ -187,7 +187,7 @@
 	return nil;
 }
 
-void
+int
 copen(Chan *c)
 {
 	Mntcache *m, *f, **l;
@@ -195,19 +195,20 @@
 	/* directories aren't cacheable */
 	if(c->qid.type&QTDIR){
 		c->mcp = nil;
-		return;
+		return 0;
 	}
 
 	lock(&cache);
-	m = clookup(c, 1);
-	if(m == nil)
-		m = cache.head;
-	else if(m->qid.vers == c->qid.vers) {
+	m = clookup(c, 0);
+	if(m != nil){
 		ctail(m);
 		unlock(&cache);
 		c->mcp = m;
-		return;
+		return 1;
 	}
+	m = clookup(c, 1);
+	if(m == nil)
+		m = cache.head;
 	ctail(m);
 
 	l = &cache.hash[m->qid.path%NHASH];
@@ -234,7 +235,7 @@
 			unlock(&cache);
 			cacheunlock(m);
 			c->mcp = f;
-			return;
+			return 1;
 		}
 	}
 
@@ -251,10 +252,9 @@
 	m->rah.vers = m->qid.vers;
 	mntrahinit(&m->rah);
 	cnodata(m);
-
 	cacheunlock(m);
-
 	c->mcp = m;
+	return 0;
 }
 
 enum {
@@ -480,6 +480,31 @@
 		return;
 	}
 	cachedata(m, buf, len, off);
+}
+
+void
+ctrunc(Chan *c)
+{
+	Mntcache *m;
+
+	if(c->qid.type&QTDIR)
+		return;
+
+	if((c->flag&COPEN) == 0){
+		lock(&cache);
+		c->mcp = clookup(c, 0);
+		unlock(&cache);
+	}
+
+	m = ccache(c);
+	if(m == nil)
+		return;
+	mntrahinit(&m->rah);
+	cnodata(m);
+	cacheunlock(m);
+
+	if((c->flag&COPEN) == 0)
+		c->mcp = nil;
 }
 
 void
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -521,8 +521,11 @@
 	poperror();
 	mntfree(r);
 
-	if(c->flag & CCACHE)
-		copen(c);
+	if(c->flag & CCACHE){
+		if(copen(c))
+		if(type == Tcreate || (omode&OTRUNC) != 0)
+			ctrunc(c);
+	}
 
 	return c;
 }
@@ -620,6 +623,11 @@
 	mountrpc(m, r);
 	poperror();
 	mntfree(r);
+
+	if(c->flag & CCACHE)
+	if(GBIT64(&dp[STATFIXLEN-4*BIT16SZ-BIT64SZ]) != ~0ULL)
+		ctrunc(c);
+
 	return n;
 }
 
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -41,7 +41,7 @@
 int		consactive(void);
 void		(*consdebug)(void);
 void		cpushutdown(void);
-void		copen(Chan*);
+int		copen(Chan*);
 void		cclunk(Chan*);
 Block*		concatblock(Block*);
 Block*		copyblock(Block*, int);
@@ -48,6 +48,7 @@
 void		copypage(Page*, Page*);
 void		countpagerefs(ulong*, int);
 int		cread(Chan*, uchar*, int, vlong);
+void		ctrunc(Chan*);
 void		cunmount(Chan*, Chan*);
 void		cupdate(Chan*, uchar*, int, vlong);
 void		cwrite(Chan*, uchar*, int, vlong);
--- a/sys/src/libsec/port/chacha.c
+++ b/sys/src/libsec/port/chacha.c
@@ -57,7 +57,8 @@
 {
 	if(keylen != 256/8 && keylen != 128/8)
 		sysfatal("invalid chacha key length");
-	if(ivlen != 96/8 && ivlen != 64/8)
+	if(ivlen != 64/8 && ivlen != 96/8
+	&& ivlen != 128/8 && ivlen != 192/8)	/* hchacha, xchacha */
 		sysfatal("invalid chacha iv length");
 	if(rounds == 0)
 		rounds = 20;
@@ -70,7 +71,16 @@
 		load(&s->input[4], key, 4);
 		load(&s->input[8], key, 4);
 	}
-	s->ivwords = ivlen/sizeof(u32int);
+	s->xkey[0] = s->input[4];
+	s->xkey[1] = s->input[5];
+	s->xkey[2] = s->input[6];
+	s->xkey[3] = s->input[7];
+	s->xkey[4] = s->input[8];
+	s->xkey[5] = s->input[9];
+	s->xkey[6] = s->input[10];
+	s->xkey[7] = s->input[11];
+
+	s->ivwords = ivlen/4;
 	s->input[12] = 0;
 	s->input[13] = 0;
 	if(iv == nil){
@@ -80,20 +90,6 @@
 		chacha_setiv(s, iv);
 }
 
-void
-chacha_setiv(Chachastate *s, uchar *iv)
-{
-	load(&s->input[16 - s->ivwords], iv, s->ivwords);
-}
-
-void
-chacha_setblock(Chachastate *s, u64int blockno)
-{
-	s->input[12] = blockno;
-	if(s->ivwords == 2)
-		s->input[13] = blockno>>32;
-}
-
 static void
 dorounds(u32int x[Blockwords], int rounds)
 {
@@ -111,6 +107,83 @@
 }
 
 static void
+hchachablock(uchar h[32], Chachastate *s)
+{
+	u32int x[16];
+
+	x[0] = s->input[0];
+	x[1] = s->input[1];
+	x[2] = s->input[2];
+	x[3] = s->input[3];
+	x[4] = s->input[4];
+	x[5] = s->input[5];
+	x[6] = s->input[6];
+	x[7] = s->input[7];
+	x[8] = s->input[8];
+	x[9] = s->input[9];
+	x[10] = s->input[10];
+	x[11] = s->input[11];
+	x[12] = s->input[12];
+	x[13] = s->input[13];
+	x[14] = s->input[14];
+	x[15] = s->input[15];
+
+	dorounds(x, s->rounds);
+
+	PUT4(h+0*4, x[0]);
+	PUT4(h+1*4, x[1]);
+	PUT4(h+2*4, x[2]);
+	PUT4(h+3*4, x[3]);
+	PUT4(h+4*4, x[12]);
+	PUT4(h+5*4, x[13]);
+	PUT4(h+6*4, x[14]);
+	PUT4(h+7*4, x[15]);
+}
+
+void
+chacha_setiv(Chachastate *s, uchar *iv)
+{
+	if(s->ivwords == 192/32){
+		/* xchacha with 192-bit iv */
+		u32int counter[2];
+		uchar h[32];
+
+		s->input[4] = s->xkey[0];
+		s->input[5] = s->xkey[1];
+		s->input[6] = s->xkey[2];
+		s->input[7] = s->xkey[3];
+		s->input[8] = s->xkey[4];
+		s->input[9] = s->xkey[5];
+		s->input[10] = s->xkey[6];
+		s->input[11] = s->xkey[7];
+
+		counter[0] = s->input[12];
+		counter[1] = s->input[13];
+
+		load(&s->input[12], iv, 4);
+
+		hchachablock(h, s);
+		load(&s->input[4], h, 8);
+		memset(h, 0, 32);
+
+		s->input[12] = counter[0];
+		s->input[13] = counter[1];
+
+		load(&s->input[14], iv+16, 2);
+		return;
+	}
+	load(&s->input[16 - s->ivwords], iv, s->ivwords);
+}
+
+void
+chacha_setblock(Chachastate *s, u64int blockno)
+{
+	s->input[12] = blockno;
+	if(s->ivwords != 3)
+		s->input[13] = blockno>>32;
+}
+
+static void
 encryptblock(Chachastate *s, uchar *src, uchar *dst)
 {
 	u32int x[Blockwords];
@@ -143,7 +216,7 @@
 		dst += 16;
 	}
 
-	if(++s->input[12] == 0 && s->ivwords == 2)
+	if(++s->input[12] == 0 && s->ivwords != 3)
 		s->input[13]++;
 }
 
@@ -168,4 +241,14 @@
 chacha_encrypt(uchar *buf, ulong bytes, Chachastate *s)
 {
 	chacha_encrypt2(buf, buf, bytes, s);
+}
+
+void
+hchacha(uchar h[32], uchar *key, ulong keylen, uchar nonce[16], int rounds)
+{
+	Chachastate s[1];
+
+	setupChachastate(s, key, keylen, nonce, 16, rounds);
+	hchachablock(h, s);
+	memset(s, 0, sizeof(s));
 }
--- a/sys/src/libsec/port/chachatest.c
+++ b/sys/src/libsec/port/chachatest.c
@@ -42,6 +42,26 @@
 	0x87, 0x4d
 };
 
+uchar	xcckey[] = {
+	0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, 0x46, 0xc7,
+	0x60, 0x09, 0x54, 0x9e, 0xac, 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, 0x44, 0xf6, 0x83, 0x89,
+};
+uchar	xcciv[] = {
+	0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
+	0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37,
+};
+uchar	xccref[] = {
+	0x4f, 0xeb, 0xf2, 0xfe, 0x4b, 0x35, 0x9c, 0x50, 0x8d, 0xc5, 0xe8, 0xb5, 0x98, 0x0c, 0x88, 0xe3,
+	0x89, 0x46, 0xd8, 0xf1, 0x8f, 0x31, 0x34, 0x65, 0xc8, 0x62, 0xa0, 0x87, 0x82, 0x64, 0x82, 0x48,
+	0x01, 0x8d, 0xac, 0xdc, 0xb9, 0x04, 0x17, 0x88, 0x53, 0xa4, 0x6d, 0xca, 0x3a, 0x0e, 0xaa, 0xee,
+	0x74, 0x7c, 0xba, 0x97, 0x43, 0x4e, 0xaf, 0xfa, 0xd5, 0x8f, 0xea, 0x82, 0x22, 0x04, 0x7e, 0x0d,
+	0xe6, 0xc3, 0xa6, 0x77, 0x51, 0x06, 0xe0, 0x33, 0x1a, 0xd7, 0x14, 0xd2, 0xf2, 0x7a, 0x55, 0x64,
+	0x13, 0x40, 0xa1, 0xf1, 0xdd, 0x9f, 0x94, 0x53, 0x2e, 0x68, 0xcb, 0x24, 0x1c, 0xbd, 0xd1, 0x50,
+	0x97, 0x0d, 0x14, 0xe0, 0x5c, 0x5b, 0x17, 0x31, 0x93, 0xfb, 0x14, 0xf5, 0x1c, 0x41, 0xf3, 0x93,
+	0x83, 0x5b, 0xf7, 0xf4, 0x16, 0xa7, 0xe0, 0xbb, 0xa8, 0x1f, 0xfb, 0x8b, 0x13, 0xaf, 0x0e, 0x21,
+	0x69, 0x1d, 0x7e, 0xce, 0xc9, 0x3b, 0x75, 0xe6, 0xe4, 0x18, 0x3a,
+};
+
 uchar	ccpaad[] = {
 	0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 };
@@ -103,6 +123,26 @@
 	}
 	print("\n");
 
+
+	print("xchacha key:\n");
+	printblock(xcckey, sizeof(xcckey));
+
+	print("xchacha iv:\n");
+	printblock(xcciv, sizeof(xcciv));
+
+	setupChachastate(&s, xcckey, sizeof(xcckey), xcciv, sizeof(xcciv), 20);
+	memset(rfcout, 0, sizeof(xccref));
+	chacha_encrypt(rfcout, sizeof(xccref), &s);
+
+	print("xchacha out:\n");
+	printblock(rfcout, sizeof(xccref));
+	if(memcmp(rfcout, xccref, sizeof(xccref)) != 0){
+		print("failure of vision\n");
+		exits("wrong");
+	}
+	print("\n");
+
+
 	print("ccpoly key:\n");
 	printblock(ccpkey, sizeof(ccpkey));
 
@@ -135,6 +175,7 @@
 		exits("wrong");
 	}
 	print("\n");
+
 
 	print("ccpoly64 key:\n");
 	printblock(ccp64key, sizeof(ccp64key));
--- a/sys/src/libsec/port/salsa.c
+++ b/sys/src/libsec/port/salsa.c
@@ -34,7 +34,8 @@
 {
 	if(keylen != 256/8 && keylen != 128/8)
 		sysfatal("invalid salsa key length");
-	if(ivlen != 64/8 && ivlen != 128/8 && ivlen != 192/8)
+	if(ivlen != 64/8
+	&& ivlen != 128/8 && ivlen != 192/8)	/* hsalsa, xsalsa */
 		sysfatal("invalid salsa iv length");
 	if(rounds == 0)
 		rounds = 20;
@@ -54,14 +55,14 @@
 		load(&s->input[11], key, 4);
 		load(&s->input[15], tau +4*3, 1);
 	}
-	s->key[0] = s->input[1];
-	s->key[1] = s->input[2];
-	s->key[2] = s->input[3];
-	s->key[3] = s->input[4];
-	s->key[4] = s->input[11];
-	s->key[5] = s->input[12];
-	s->key[6] = s->input[13];
-	s->key[7] = s->input[14];
+	s->xkey[0] = s->input[1];
+	s->xkey[1] = s->input[2];
+	s->xkey[2] = s->input[3];
+	s->xkey[3] = s->input[4];
+	s->xkey[4] = s->input[11];
+	s->xkey[5] = s->input[12];
+	s->xkey[6] = s->input[13];
+	s->xkey[7] = s->input[14];
 
 	s->ivwords = ivlen/4;
 	s->input[8] = 0;
@@ -152,7 +153,7 @@
 salsa_setiv(Salsastate *s, uchar *iv)
 {
 	if(s->ivwords == 128/32){
-		/* hsalsa 128-bit iv */
+		/* hsalsa with 128-bit iv */
 		load(&s->input[6], iv, 4);
 		return;
 	}
@@ -164,14 +165,14 @@
 		counter[0] = s->input[8];
 		counter[1] = s->input[9];
 
-		s->input[1] = s->key[0];
-		s->input[2] = s->key[1];
-		s->input[3] = s->key[2];
-		s->input[4] = s->key[3];
-		s->input[11] = s->key[4];
-		s->input[12] = s->key[5];
-		s->input[13] = s->key[6];
-		s->input[14] = s->key[7];
+		s->input[1] = s->xkey[0];
+		s->input[2] = s->xkey[1];
+		s->input[3] = s->xkey[2];
+		s->input[4] = s->xkey[3];
+		s->input[11] = s->xkey[4];
+		s->input[12] = s->xkey[5];
+		s->input[13] = s->xkey[6];
+		s->input[14] = s->xkey[7];
 
 		load(&s->input[6], iv, 4);