diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-01-12 20:17:52 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-01-12 20:17:52 +0100 |
commit | bdc1b187c45dbaeaa7dadce4d7999d9d550ec78f (patch) | |
tree | 2edaaab35888b82013f15c31945ebed1bca755ef | |
parent | a0cc369c15bdd404e1a60b4fd5b3a5156a041f74 (diff) | |
parent | 2e23780d2f4f1e3a55a096227a01995d0f0c2e52 (diff) | |
download | plan9front-bdc1b187c45dbaeaa7dadce4d7999d9d550ec78f.tar.xz |
merge
-rw-r--r-- | sys/include/ape/libsec.h | 6 | ||||
-rw-r--r-- | sys/include/libsec.h | 6 | ||||
-rw-r--r-- | sys/man/2/chacha | 16 | ||||
-rw-r--r-- | sys/src/9/ip/tcp.c | 2 | ||||
-rw-r--r-- | sys/src/9/port/cache.c | 45 | ||||
-rw-r--r-- | sys/src/9/port/devmnt.c | 12 | ||||
-rw-r--r-- | sys/src/9/port/portfns.h | 3 | ||||
-rw-r--r-- | sys/src/libsec/port/chacha.c | 117 | ||||
-rw-r--r-- | sys/src/libsec/port/chachatest.c | 41 | ||||
-rw-r--r-- | sys/src/libsec/port/salsa.c | 37 |
10 files changed, 232 insertions, 53 deletions
diff --git a/sys/include/ape/libsec.h b/sys/include/ape/libsec.h index 11e8b5f61..96007de48 100644 --- a/sys/include/ape/libsec.h +++ b/sys/include/ape/libsec.h @@ -101,6 +101,7 @@ enum ChachaBsize= 64, ChachaKeylen= 256/8, ChachaIVlen= 96/8, + XChachaIVlen= 192/8, }; typedef struct Chachastate Chachastate; @@ -115,6 +116,7 @@ struct Chachastate u32int iv[3]; }; }; + u32int xkey[8]; int rounds; int ivwords; }; @@ -125,6 +127,8 @@ void chacha_setblock(Chachastate*, u64int); 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 @@ typedef struct Salsastate Salsastate; struct Salsastate { u32int input[16]; - u32int key[8]; + u32int xkey[8]; int rounds; int ivwords; }; diff --git a/sys/include/libsec.h b/sys/include/libsec.h index 348f4f967..030faac8c 100644 --- a/sys/include/libsec.h +++ b/sys/include/libsec.h @@ -93,6 +93,7 @@ enum ChachaBsize= 64, ChachaKeylen= 256/8, ChachaIVlen= 96/8, + XChachaIVlen= 192/8, }; typedef struct Chachastate Chachastate; @@ -107,6 +108,7 @@ struct Chachastate u32int iv[3]; }; }; + u32int xkey[8]; int rounds; int ivwords; }; @@ -117,6 +119,8 @@ void chacha_setblock(Chachastate*, u64int); 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 @@ typedef struct Salsastate Salsastate; struct Salsastate { u32int input[16]; - u32int key[8]; + u32int xkey[8]; int rounds; int ivwords; }; diff --git a/sys/man/2/chacha b/sys/man/2/chacha index b339e9dc0..21ce09ea0 100644 --- 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_setblock(Chachastate *s, u64int blockno) 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 @@ a 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 @@ -94,6 +100,10 @@ allowing seeking in an encrypted stream. 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 .I ccpoly_decrypt diff --git a/sys/src/9/ip/tcp.c b/sys/src/9/ip/tcp.c index b612bbd5a..f241a5c8e 100644 --- a/sys/src/9/ip/tcp.c +++ b/sys/src/9/ip/tcp.c @@ -3282,6 +3282,8 @@ tcpporthogdefensectl(char *val) 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) diff --git a/sys/src/9/port/cache.c b/sys/src/9/port/cache.c index 306228731..37a4d6813 100644 --- a/sys/src/9/port/cache.c +++ b/sys/src/9/port/cache.c @@ -187,7 +187,7 @@ ccache(Chan *c) return nil; } -void +int copen(Chan *c) { Mntcache *m, *f, **l; @@ -195,19 +195,20 @@ copen(Chan *c) /* 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 @@ copen(Chan *c) unlock(&cache); cacheunlock(m); c->mcp = f; - return; + return 1; } } @@ -251,10 +252,9 @@ copen(Chan *c) m->rah.vers = m->qid.vers; mntrahinit(&m->rah); cnodata(m); - cacheunlock(m); - c->mcp = m; + return 0; } enum { @@ -483,6 +483,31 @@ cwrite(Chan* c, uchar *buf, int len, vlong 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 cclunk(Chan *c) { Mntcache *m; diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c index 095381d57..fc5ccbf1e 100644 --- a/sys/src/9/port/devmnt.c +++ b/sys/src/9/port/devmnt.c @@ -521,8 +521,11 @@ mntopencreate(int type, Chan *c, char *name, int omode, ulong perm) 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 @@ mntwstat(Chan *c, uchar *dp, int n) mountrpc(m, r); poperror(); mntfree(r); + + if(c->flag & CCACHE) + if(GBIT64(&dp[STATFIXLEN-4*BIT16SZ-BIT64SZ]) != ~0ULL) + ctrunc(c); + return n; } diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h index 7c7eec461..5564ce0c8 100644 --- a/sys/src/9/port/portfns.h +++ b/sys/src/9/port/portfns.h @@ -41,13 +41,14 @@ void confinit(void); 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); 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); diff --git a/sys/src/libsec/port/chacha.c b/sys/src/libsec/port/chacha.c index c4f8aca77..49b7ee906 100644 --- a/sys/src/libsec/port/chacha.c +++ b/sys/src/libsec/port/chacha.c @@ -57,7 +57,8 @@ setupChachastate(Chachastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivle { 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 @@ setupChachastate(Chachastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivle 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 @@ setupChachastate(Chachastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivle 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 @@ dorounds(u32int x[Blockwords], int rounds) } 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 @@ encryptblock(Chachastate *s, uchar *src, uchar *dst) dst += 16; } - if(++s->input[12] == 0 && s->ivwords == 2) + if(++s->input[12] == 0 && s->ivwords != 3) s->input[13]++; } @@ -169,3 +242,13 @@ 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)); +} diff --git a/sys/src/libsec/port/chachatest.c b/sys/src/libsec/port/chachatest.c index 92a5d0897..49b4ff104 100644 --- a/sys/src/libsec/port/chachatest.c +++ b/sys/src/libsec/port/chachatest.c @@ -42,6 +42,26 @@ uchar rfcref[] = { 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 @@ main(int argc, char **argv) } 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)); @@ -136,6 +176,7 @@ main(int argc, char **argv) } print("\n"); + print("ccpoly64 key:\n"); printblock(ccp64key, sizeof(ccp64key)); diff --git a/sys/src/libsec/port/salsa.c b/sys/src/libsec/port/salsa.c index 648f6bca1..3a0ba940b 100644 --- a/sys/src/libsec/port/salsa.c +++ b/sys/src/libsec/port/salsa.c @@ -34,7 +34,8 @@ setupSalsastate(Salsastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivlen, { 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 @@ setupSalsastate(Salsastate *s, uchar *key, ulong keylen, uchar *iv, ulong ivlen, 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 @@ void 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 @@ salsa_setiv(Salsastate *s, uchar *iv) 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); |