From fa01fe0b18e1fe674db671a6ae1dd32c16c5230a Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Mon, 24 Jun 2024 01:24:03 +0300 Subject: [PATCH 01/21] libsec: add pbkdf2 Add PBKDF2 support. http://9legacy.org/9legacy/patch/libsec-pbkdf2.diff --- include/libsec.h | 4 ++++ libsec/Makefile | 1 + libsec/pbkdf2.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 libsec/pbkdf2.c diff --git a/include/libsec.h b/include/libsec.h index 96d4811..903c448 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -440,3 +440,7 @@ int okThumbprint(uchar *sha1, Thumbprint *ok); /* readcert.c */ uchar *readcert(char *filename, int *pcertlen); PEMChain*readcertchain(char *filename); + +/* password-based key derivation function 2 (rfc2898) */ +void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen, + DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen); diff --git a/libsec/Makefile b/libsec/Makefile index 7ba537d..7dfee94 100644 --- a/libsec/Makefile +++ b/libsec/Makefile @@ -52,6 +52,7 @@ OFILES=\ sha2_128.$O\ sha2block128.$O\ smallprimes.$O\ + pbkdf2.$O\ default: $(LIB) $(LIB): $(OFILES) diff --git a/libsec/pbkdf2.c b/libsec/pbkdf2.c new file mode 100644 index 0000000..da3a646 --- /dev/null +++ b/libsec/pbkdf2.c @@ -0,0 +1,34 @@ +#include "os.h" +#include + +/* rfc2898 */ +void +pbkdf2_x(p, plen, s, slen, rounds, d, dlen, x, xlen) + uchar *p, *s, *d; + ulong plen, slen, dlen, rounds; + DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); + int xlen; +{ + uchar block[256], tmp[256]; + ulong i, j, k, n; + DigestState *ds; + + assert(xlen <= sizeof(tmp)); + + for(i = 1; dlen > 0; i++, d += n, dlen -= n){ + tmp[3] = i; + tmp[2] = i >> 8; + tmp[1] = i >> 16; + tmp[0] = i >> 24; + ds = (*x)(s, slen, p, plen, nil, nil); + (*x)(tmp, 4, p, plen, block, ds); + memmove(tmp, block, xlen); + for(j = 1; j < rounds; j++){ + (*x)(tmp, xlen, p, plen, tmp, nil); + for(k=0; k xlen ? xlen : dlen; + memmove(d, block, n); + } +} From 22e00efd432f3ebe702278b58bb9f56c83bedcd8 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Mon, 24 Jun 2024 01:45:23 +0300 Subject: [PATCH 02/21] libsec: add rfc5869 hmac-based key derivation function hkdf_x() http://9legacy.org/9legacy/patch/libsec-hkdf_x.diff --- include/libsec.h | 4 ++++ libsec/Makefile | 1 + libsec/hkdf.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 libsec/hkdf.c diff --git a/include/libsec.h b/include/libsec.h index 903c448..cc86d3b 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -444,3 +444,7 @@ PEMChain*readcertchain(char *filename); /* password-based key derivation function 2 (rfc2898) */ void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen, DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen); + +/* hmac-based key derivation function (rfc5869) */ +void hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, uchar *key, ulong nkey, uchar *d, ulong dlen, + DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen); diff --git a/libsec/Makefile b/libsec/Makefile index 7dfee94..b3ce7e7 100644 --- a/libsec/Makefile +++ b/libsec/Makefile @@ -53,6 +53,7 @@ OFILES=\ sha2block128.$O\ smallprimes.$O\ pbkdf2.$O\ + hkdf.$O\ default: $(LIB) $(LIB): $(OFILES) diff --git a/libsec/hkdf.c b/libsec/hkdf.c new file mode 100644 index 0000000..5e3f27b --- /dev/null +++ b/libsec/hkdf.c @@ -0,0 +1,36 @@ +#include "os.h" +#include + +/* rfc5869 */ +void +hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, + uchar *key, ulong nkey, uchar *d, ulong dlen, + DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen) +{ + uchar prk[256], tmp[256], cnt; + DigestState *ds; + + assert(xlen <= sizeof(tmp)); + + memset(tmp, 0, xlen); + if(nsalt == 0){ + salt = tmp; + nsalt = xlen; + } + /* note that salt and key are swapped in this case */ + (*x)(key, nkey, salt, nsalt, prk, nil); + ds = nil; + for(cnt=1;; cnt++) { + if(ninfo > 0) + ds = (*x)(info, ninfo, prk, xlen, nil, ds); + (*x)(&cnt, 1, prk, xlen, tmp, ds); + if(dlen <= xlen){ + memmove(d, tmp, dlen); + break; + } + memmove(d, tmp, xlen); + dlen -= xlen; + d += xlen; + ds = (*x)(tmp, xlen, prk, xlen, nil, nil); + } +} From 71e5454a08a2c58365d7c2ca9e81ecaa2bec434c Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Mon, 24 Jun 2024 04:38:58 +0300 Subject: [PATCH 03/21] libsec: add poly1305 --- include/libsec.h | 3 + libsec/Makefile | 1 + libsec/poly1305.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 libsec/poly1305.c diff --git a/include/libsec.h b/include/libsec.h index cc86d3b..8f2ee09 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -183,6 +183,7 @@ enum MD4dlen= 16, /* MD4 digest length */ MD5dlen= 16, /* MD5 digest length */ AESdlen= 16, /* TODO: see rfc */ + Poly1305dlen= 16, /* Poly1305 digest length */ Hmacblksz = 64, /* in bytes; from rfc2104 */ }; @@ -234,6 +235,8 @@ MD5state* md5unpickle(char*); char* sha1pickle(SHA1state*); SHA1state* sha1unpickle(char*); +DigestState* poly1305(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); + /* * random number generation */ diff --git a/libsec/Makefile b/libsec/Makefile index b3ce7e7..0039900 100644 --- a/libsec/Makefile +++ b/libsec/Makefile @@ -54,6 +54,7 @@ OFILES=\ smallprimes.$O\ pbkdf2.$O\ hkdf.$O\ + poly1305.$O\ default: $(LIB) $(LIB): $(OFILES) diff --git a/libsec/poly1305.c b/libsec/poly1305.c new file mode 100644 index 0000000..42f9ac4 --- /dev/null +++ b/libsec/poly1305.c @@ -0,0 +1,192 @@ +#include +#include +#include + +/* + poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition + + derived from http://github.com/floodberry/poly1305-donna +*/ + +#define U8TO32(p) ((u32int)(p)[0] | (u32int)(p)[1]<<8 | (u32int)(p)[2]<<16 | (u32int)(p)[3]<<24) +#define U32TO8(p, v) (p)[0]=(v), (p)[1]=(v)>>8, (p)[2]=(v)>>16, (p)[3]=(v)>>24 + +/* (r,s) = (key[0:15],key[16:31]), the one time key */ +DigestState* +poly1305(uchar *m, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s) +{ + u32int r0,r1,r2,r3,r4, s1,s2,s3,s4, h0,h1,h2,h3,h4, g0,g1,g2,g3,g4; + u64int d0,d1,d2,d3,d4, f; + u32int hibit, mask, c; + + if(s == nil){ + s = malloc(sizeof(*s)); + if(s == nil) + return nil; + memset(s, 0, sizeof(*s)); + s->malloced = 1; + } + + if(s->seeded == 0){ + assert(klen == 32); + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + s->state[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff; + s->state[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03; + s->state[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff; + s->state[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff; + s->state[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + s->state[5] = 0; + s->state[6] = 0; + s->state[7] = 0; + s->state[8] = 0; + s->state[9] = 0; + + /* save pad for later */ + s->state[10] = U8TO32(&key[16]); + s->state[11] = U8TO32(&key[20]); + s->state[12] = U8TO32(&key[24]); + s->state[13] = U8TO32(&key[28]); + + s->seeded = 1; + } + + if(s->blen){ + c = 16 - s->blen; + if(c > len) + c = len; + memmove(s->buf + s->blen, m, c); + len -= c, m += c; + s->blen += c; + if(s->blen == 16){ + s->blen = 0; + poly1305(s->buf, 16, key, klen, nil, s); + } + } + + r0 = s->state[0]; + r1 = s->state[1]; + r2 = s->state[2]; + r3 = s->state[3]; + r4 = s->state[4]; + + h0 = s->state[5]; + h1 = s->state[6]; + h2 = s->state[7]; + h3 = s->state[8]; + h4 = s->state[9]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + hibit = 1<<24; /* 1<<128 */ + + while(len >= 16){ +Block: + /* h += m[i] */ + h0 += (U8TO32(&m[0]) ) & 0x3ffffff; + h1 += (U8TO32(&m[3]) >> 2) & 0x3ffffff; + h2 += (U8TO32(&m[6]) >> 4) & 0x3ffffff; + h3 += (U8TO32(&m[9]) >> 6) & 0x3ffffff; + h4 += (U8TO32(&m[12])>> 8) | hibit; + + /* h *= r */ + d0 = ((u64int)h0 * r0) + ((u64int)h1 * s4) + ((u64int)h2 * s3) + ((u64int)h3 * s2) + ((u64int)h4 * s1); + d1 = ((u64int)h0 * r1) + ((u64int)h1 * r0) + ((u64int)h2 * s4) + ((u64int)h3 * s3) + ((u64int)h4 * s2); + d2 = ((u64int)h0 * r2) + ((u64int)h1 * r1) + ((u64int)h2 * r0) + ((u64int)h3 * s4) + ((u64int)h4 * s3); + d3 = ((u64int)h0 * r3) + ((u64int)h1 * r2) + ((u64int)h2 * r1) + ((u64int)h3 * r0) + ((u64int)h4 * s4); + d4 = ((u64int)h0 * r4) + ((u64int)h1 * r3) + ((u64int)h2 * r2) + ((u64int)h3 * r1) + ((u64int)h4 * r0); + + /* (partial) h %= p */ + c = (u32int)(d0 >> 26); h0 = (u32int)d0 & 0x3ffffff; + d1 += c; c = (u32int)(d1 >> 26); h1 = (u32int)d1 & 0x3ffffff; + d2 += c; c = (u32int)(d2 >> 26); h2 = (u32int)d2 & 0x3ffffff; + d3 += c; c = (u32int)(d3 >> 26); h3 = (u32int)d3 & 0x3ffffff; + d4 += c; c = (u32int)(d4 >> 26); h4 = (u32int)d4 & 0x3ffffff; + h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; + h1 += c; + + len -= 16, m += 16; + } + + if(len){ + s->blen = len; + memmove(s->buf, m, len); + } + + if(digest == nil){ + s->state[5] = h0; + s->state[6] = h1; + s->state[7] = h2; + s->state[8] = h3; + s->state[9] = h4; + return s; + } + + if(len){ + m = s->buf; + m[len++] = 1; + while(len < 16) + m[len++] = 0; + hibit = 0; + goto Block; + } + + c = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + c - (1 << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> 31) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = (h0 ) | (h1 << 26); + h1 = (h1 >> 6) | (h2 << 20); + h2 = (h2 >> 12) | (h3 << 14); + h3 = (h3 >> 18) | (h4 << 8); + + /* digest = (h + pad) % (2^128) */ + f = (u64int)h0 + s->state[10] ; h0 = (u32int)f; + f = (u64int)h1 + s->state[11] + (f >> 32); h1 = (u32int)f; + f = (u64int)h2 + s->state[12] + (f >> 32); h2 = (u32int)f; + f = (u64int)h3 + s->state[13] + (f >> 32); h3 = (u32int)f; + + U32TO8(&digest[0], h0); + U32TO8(&digest[4], h1); + U32TO8(&digest[8], h2); + U32TO8(&digest[12], h3); + + if(s->malloced){ + memset(s, 0, sizeof(*s)); + free(s); + return nil; + } + + memset(s, 0, sizeof(*s)); + return nil; +} From 658ac3f1aef572af2007eb462e2b91786f3f30c7 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Mon, 24 Jun 2024 15:22:12 +0300 Subject: [PATCH 04/21] libsec: add chacha20 poly1305 aead, allow 64 bit iv's for chacha, add tsmemcmp() http://9legacy.org/9legacy/patch/libsec-chacha-iv.diff --- include/libsec.h | 12 +++++-- libsec/Makefile | 2 ++ libsec/ccpoly.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ libsec/chacha.c | 22 +++++++++--- libsec/chachatest.c | 56 ++++++++++++++++++++++++++++-- libsec/tsmemcmp.c | 26 ++++++++++++++ 6 files changed, 192 insertions(+), 10 deletions(-) create mode 100644 libsec/ccpoly.c create mode 100644 libsec/tsmemcmp.c diff --git a/include/libsec.h b/include/libsec.h index 8f2ee09..f251798 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -104,13 +104,18 @@ struct Chachastate }; }; int rounds; + int ivwords; }; -void setupChachastate(Chachastate*, uchar*, usize, uchar*, int); -void chacha_setblock(Chachastate*, u32int); +void setupChachastate(Chachastate*, uchar*, usize, uchar*, ulong, int); +void chacha_setiv(Chachastate *, uchar*); +void chacha_setblock(Chachastate*, u64int); void chacha_encrypt(uchar*, usize, Chachastate*); void chacha_encrypt2(uchar*, uchar*, usize, Chachastate*); +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); + /* * DES definitions */ @@ -451,3 +456,6 @@ void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d /* hmac-based key derivation function (rfc5869) */ void hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, uchar *key, ulong nkey, uchar *d, ulong dlen, DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen); + +/* timing safe memcmp() */ +int tsmemcmp(void*, void*, ulong); diff --git a/libsec/Makefile b/libsec/Makefile index 0039900..53cd976 100644 --- a/libsec/Makefile +++ b/libsec/Makefile @@ -55,6 +55,8 @@ OFILES=\ pbkdf2.$O\ hkdf.$O\ poly1305.$O\ + ccpoly.$O\ + tsmemcmp.$O\ default: $(LIB) $(LIB): $(OFILES) diff --git a/libsec/ccpoly.c b/libsec/ccpoly.c new file mode 100644 index 0000000..14a8a9c --- /dev/null +++ b/libsec/ccpoly.c @@ -0,0 +1,84 @@ +#include +#include +#include + +static void +ccpolyotk(Chachastate *cs, DigestState *ds) +{ + uchar otk[ChachaBsize]; + + memset(ds, 0, sizeof(*ds)); + memset(otk, 0, 32); + chacha_setblock(cs, 0); + chacha_encrypt(otk, ChachaBsize, cs); + poly1305(nil, 0, otk, 32, nil, ds); +} + +static void +ccpolymac(uchar *buf, ulong nbuf, DigestState *ds) +{ + static uchar zeros[16] = {0}; + ulong npad; + + if(nbuf == 0) + return; + poly1305(buf, nbuf, nil, 0, nil, ds); + npad = nbuf % 16; + if(npad == 0) + return; + poly1305(zeros, 16 - npad, nil, 0, nil, ds); +} + +static void +ccpolytag(ulong ndat, ulong naad, uchar tag[16], DigestState *ds) +{ + uchar info[16]; + + info[0] = naad; + info[1] = naad>>8; + info[2] = naad>>16; + info[3] = naad>>24; + info[4] = 0; + info[5] = 0; + info[6] = 0; + info[7] = 0; + + info[8] = ndat; + info[9] = ndat>>8; + info[10] = ndat>>16; + info[11] = ndat>>24; + info[12] = 0; + info[13] = 0; + info[14] = 0; + info[15] = 0; + + poly1305(info, 16, nil, 0, tag, ds); +} + +void +ccpoly_encrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs) +{ + DigestState ds; + + ccpolyotk(cs, &ds); + ccpolymac(aad, naad, &ds); + chacha_encrypt(dat, ndat, cs); + ccpolymac(dat, ndat, &ds); + ccpolytag(ndat, naad, tag, &ds); +} + +int +ccpoly_decrypt(uchar *dat, ulong ndat, uchar *aad, ulong naad, uchar tag[16], Chachastate *cs) +{ + DigestState ds; + uchar tmp[16]; + + ccpolyotk(cs, &ds); + ccpolymac(aad, naad, &ds); + ccpolymac(dat, ndat, &ds); + ccpolytag(ndat, naad, tmp, &ds); + if(tsmemcmp(tag, tmp, 16) != 0) + return -1; + chacha_encrypt(dat, ndat, cs); + return 0; +} diff --git a/libsec/chacha.c b/libsec/chacha.c index 3f7b9f5..bcf9468 100644 --- a/libsec/chacha.c +++ b/libsec/chacha.c @@ -54,10 +54,12 @@ load(u32int *d, uchar *s, int nw) } void -setupChachastate(Chachastate *s, uchar *key, usize keylen, uchar *iv, int rounds) +setupChachastate(Chachastate *s, uchar *key, usize keylen, uchar *iv, ulong ivlen, int rounds) { if(keylen != 256/8 && keylen != 128/8) sysfatal("invalid chacha key length"); + if(ivlen != 96/8 && ivlen != 64/8) + sysfatal("invalid chacha iv length"); if(rounds == 0) rounds = 20; s->rounds = rounds; @@ -69,19 +71,28 @@ setupChachastate(Chachastate *s, uchar *key, usize keylen, uchar *iv, int rounds load(&s->input[4], key, 4); load(&s->input[8], key, 4); } + s->ivwords = ivlen/sizeof(u32int); s->input[12] = 0; + s->input[13] = 0; if(iv == nil){ - s->input[13] = 0; s->input[14] = 0; s->input[15] = 0; }else - load(&s->input[13], iv, 3); + chacha_setiv(s, iv); } void -chacha_setblock(Chachastate *s, u32int blockno) +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 @@ -148,7 +159,8 @@ encryptblock(Chachastate *s, uchar *src, uchar *dst) } #endif - s->input[12]++; + if(++s->input[12] == 0 && s->ivwords == 2) + s->input[13]++; } void diff --git a/libsec/chachatest.c b/libsec/chachatest.c index 7949c6f..c3d446b 100644 --- a/libsec/chachatest.c +++ b/libsec/chachatest.c @@ -31,7 +31,7 @@ u32int rfccount = 1; char rfctext[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, " "sunscreen would be it."; uchar rfcout[3*ChachaBsize]; -uchar rfcref[3*ChachaBsize] = { +uchar rfcref[] = { 0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81, 0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b, 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab, 0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57, @@ -42,10 +42,26 @@ uchar rfcref[3*ChachaBsize] = { 0x87, 0x4d }; +uchar ccpaad[] = { + 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, +}; +uchar ccpkey[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, +}; +uchar ccpiv[] = { + 0x07, 0x00, 0x00, 0x00, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +}; +uchar ccptag[] = { + 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91, +}; + void main(int argc, char **argv) { Chachastate s; + uchar tag[16]; int n; ARGBEGIN{ @@ -54,17 +70,51 @@ main(int argc, char **argv) print("key:\n"); printblock(rfckey, sizeof(rfckey)); n = strlen(rfctext); - setupChachastate(&s, rfckey, sizeof(rfckey), rfcnonce, 0); + setupChachastate(&s, rfckey, sizeof(rfckey), rfcnonce, sizeof(rfcnonce), 0); chacha_setblock(&s, rfccount); print("rfc in:\n"); printblock((uchar*)rfctext, n); chacha_encrypt2((uchar*)rfctext, rfcout, n, &s); print("rfc out:\n"); printblock(rfcout, n); - if(memcmp(rfcout, rfcref, sizeof(rfcout)) != 0){ + if(memcmp(rfcout, rfcref, sizeof(rfcref)) != 0){ print("failure of vision\n"); exits("wrong"); } + print("\n"); + + print("ccpoly key:\n"); + printblock(ccpkey, sizeof(ccpkey)); + + print("ccpoly iv:\n"); + printblock(ccpiv, sizeof(ccpiv)); + + setupChachastate(&s, ccpkey, sizeof(ccpkey), ccpiv, sizeof(ccpiv), 20); + + memmove(rfcout, rfctext, sizeof(rfctext)-1); + ccpoly_encrypt(rfcout, sizeof(rfctext)-1, ccpaad, sizeof(ccpaad), tag, &s); + + print("ccpoly cipher:\n"); + printblock(rfcout, sizeof(rfctext)-1); + + print("ccpoly tag:\n"); + printblock(tag, sizeof(tag)); + + if(memcmp(tag, ccptag, sizeof(tag)) != 0){ + print("bad ccpoly tag\n"); + exits("wrong"); + } + + if(ccpoly_decrypt(rfcout, sizeof(rfctext)-1, ccpaad, sizeof(ccpaad), tag, &s) != 0){ + print("ccpoly decryption failed\n"); + exits("wrong"); + } + + if(memcmp(rfcout, rfctext, sizeof(rfctext)-1) != 0){ + print("ccpoly bad decryption\n"); + exits("wrong"); + } + print("passed\n"); exits(nil); } diff --git a/libsec/tsmemcmp.c b/libsec/tsmemcmp.c new file mode 100644 index 0000000..6cc7537 --- /dev/null +++ b/libsec/tsmemcmp.c @@ -0,0 +1,26 @@ +#include +#include +#include + +/* + * timing safe memcmp() + */ +int +tsmemcmp(void *a1, void *a2, ulong n) +{ + int lt, gt, c1, c2, r, m; + uchar *s1, *s2; + + r = m = 0; + s1 = a1; + s2 = a2; + while(n--){ + c1 = *s1++; + c2 = *s2++; + lt = (c1 - c2) >> 8; + gt = (c2 - c1) >> 8; + r |= (lt - gt) & ~m; + m |= lt | gt; + } + return r; +} From 0e8b5803a8c61ca17065ba11980fd6b5b5805779 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 04:40:13 +0300 Subject: [PATCH 05/21] kern/devip-win32.c: include winsock2.h before windows.h --- kern/devip-win32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kern/devip-win32.c b/kern/devip-win32.c index 784b253..e323f1a 100644 --- a/kern/devip-win32.c +++ b/kern/devip-win32.c @@ -1,3 +1,4 @@ +#include #include #include #include "u.h" From e0cb8e407d5fb5891750df85a32eebed3b27654c Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 04:42:49 +0300 Subject: [PATCH 06/21] kern/devmnt.c: free pointer in correct order --- kern/devmnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/devmnt.c b/kern/devmnt.c index 9121bfd..06c28fe 100644 --- a/kern/devmnt.c +++ b/kern/devmnt.c @@ -1113,8 +1113,8 @@ mntfree(Mntrpc *r) lock(&mntalloc.lk); if(mntalloc.nrpcfree >= 10){ free(r->rpc); - free(r); freetag(r->request.tag); + free(r); } else{ r->list = mntalloc.rpcfree; From 64b85acfc351a44801dde741aff80a4d66fca119 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 04:46:50 +0300 Subject: [PATCH 07/21] kern/win32.c: cast to Rune* and LPCWSTR --- kern/win32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kern/win32.c b/kern/win32.c index d18c790..99e7d1c 100644 --- a/kern/win32.c +++ b/kern/win32.c @@ -287,7 +287,7 @@ WinMain(HINSTANCE x, HINSTANCE y, LPSTR z, int w) Rune *warg; if(0 && win_hasunicode()){ - warg = GetCommandLineW(); + warg = (Rune*)GetCommandLineW(); n = (wstrlen(warg)+1)*UTFmax; arg = malloc(n); wstrtoutf(arg, warg, n); @@ -465,6 +465,6 @@ showfilewrite(char *a, int n) action = Lopen; arg = cmd; } - ShellExecute(0, 0, action, arg, 0, SW_SHOWNORMAL); + ShellExecute(0, 0, (LPCWSTR)action, (LPCWSTR)arg, 0, SW_SHOWNORMAL); return n; } From 25190f42503d47bb9a490e4d6f9961f0b486e73c Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 04:50:25 +0300 Subject: [PATCH 08/21] libauthsrv/opasstokey.c: copy via memcpy instead of strncpy --- libauthsrv/opasstokey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libauthsrv/opasstokey.c b/libauthsrv/opasstokey.c index d263d4b..0db6a34 100644 --- a/libauthsrv/opasstokey.c +++ b/libauthsrv/opasstokey.c @@ -14,7 +14,7 @@ opasstokey(char *key, char *p) return 0; if(n > 10) n = 10; - strncpy((char*)t, p, n); + memcpy((char*)t, p, n); if(n >= 9){ c = p[8] & 0xf; if(n == 10) From a5deb45b688315ab8872dddb7548d8f5d3789e28 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 05:07:25 +0300 Subject: [PATCH 09/21] libsec/aes.c: remove unused aes_setupDec --- libsec/aes.c | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/libsec/aes.c b/libsec/aes.c index 3999c23..2a16e14 100644 --- a/libsec/aes.c +++ b/libsec/aes.c @@ -61,8 +61,6 @@ static uchar basekey[3][16] = { static int aes_setupEnc(ulong rk[/*4*(Nr + 1)*/], const uchar cipherKey[], int keyBits); -static int aes_setupDec(ulong rk[/*4*(Nr + 1)*/], const uchar cipherKey[], - int keyBits); static int aes_setup(ulong erk[/*4*(Nr + 1)*/], ulong drk[/*4*(Nr + 1)*/], const uchar cipherKey[], int keyBits); @@ -1240,56 +1238,6 @@ aes_setupEnc(ulong rk[/*4*(Nr + 1)*/], const uchar cipherKey[], int keyBits) return 0; } -/** - * Expand the cipher key into the decryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -static int -aes_setupDec(ulong rk[/* 4*(Nr + 1) */], const uchar cipherKey[], int keyBits) -{ - int Nr, i, j; - ulong temp; - - /* expand the cipher key: */ - Nr = aes_setupEnc(rk, cipherKey, keyBits); - /* invert the order of the round keys: */ - for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* - * apply the inverse MixColumn transform to all round keys - * but the first and the last: - */ - for (i = 1; i < Nr; i++) { - rk += 4; - rk[0] = - Td0[Te4[(rk[0] >> 24) ]] ^ - Td1[Te4[(rk[0] >> 16) & 0xff]] ^ - Td2[Te4[(rk[0] >> 8) & 0xff]] ^ - Td3[Te4[(rk[0] ) & 0xff]]; - rk[1] = - Td0[Te4[(rk[1] >> 24) ]] ^ - Td1[Te4[(rk[1] >> 16) & 0xff]] ^ - Td2[Te4[(rk[1] >> 8) & 0xff]] ^ - Td3[Te4[(rk[1] ) & 0xff]]; - rk[2] = - Td0[Te4[(rk[2] >> 24) ]] ^ - Td1[Te4[(rk[2] >> 16) & 0xff]] ^ - Td2[Te4[(rk[2] >> 8) & 0xff]] ^ - Td3[Te4[(rk[2] ) & 0xff]]; - rk[3] = - Td0[Te4[(rk[3] >> 24) ]] ^ - Td1[Te4[(rk[3] >> 16) & 0xff]] ^ - Td2[Te4[(rk[3] >> 8) & 0xff]] ^ - Td3[Te4[(rk[3] ) & 0xff]]; - } - return Nr; -} - /* using round keys in rk, perform Nr rounds of encrypting pt into ct */ void aes_encrypt(const ulong rk[/* 4*(Nr + 1) */], int Nr, const uchar pt[16], From 96826483fe0122f6024777eaf59c791e2d4254a9 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 05:13:03 +0300 Subject: [PATCH 10/21] include/libsec.h, libsec/des.c: fix inconsistent prototypes for des --- include/libsec.h | 4 ++-- libsec/des.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/libsec.h b/include/libsec.h index f251798..03c1ca2 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -137,7 +137,7 @@ struct DESstate void setupDESstate(DESstate *s, uchar key[8], uchar *ivec); void des_key_setup(uchar[8], ulong[32]); -void block_cipher(ulong*, uchar*, int); +void block_cipher(ulong[32], uchar[8], int); void desCBCencrypt(uchar*, int, DESstate*); void desCBCdecrypt(uchar*, int, DESstate*); void desECBencrypt(uchar*, int, DESstate*); @@ -168,7 +168,7 @@ struct DES3state }; void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec); -void triple_block_cipher(ulong keys[3][32], uchar*, int); +void triple_block_cipher(ulong keys[3][32], uchar[8], int); void des3CBCencrypt(uchar*, int, DES3state*); void des3CBCdecrypt(uchar*, int, DES3state*); void des3ECBencrypt(uchar*, int, DES3state*); diff --git a/libsec/des.c b/libsec/des.c index c54541c..090fd4b 100644 --- a/libsec/des.c +++ b/libsec/des.c @@ -369,7 +369,7 @@ keycompperm(u32int left, u32int right, ulong *ek) } void -des_key_setup(uchar key[8], ulong *ek) +des_key_setup(uchar key[8], ulong ek[32]) { u32int left, right, v0, v1; @@ -471,7 +471,7 @@ des64to56(uchar *k64, uchar *k56) } void -key_setup(uchar key[7], ulong *ek) +key_setup(uchar key[7], ulong ek[32]) { uchar k64[8]; From 3d41c3423aad5f82114ada2c334491c46948559a Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 05:17:59 +0300 Subject: [PATCH 11/21] include/libsec.h: have 16 32-bit words in DigestState to avoid out of bounds warnings for poly1305 --- include/libsec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libsec.h b/include/libsec.h index 03c1ca2..459f8ee 100644 --- a/include/libsec.h +++ b/include/libsec.h @@ -198,7 +198,7 @@ struct DigestState { uvlong len; union { - u32int state[8]; + u32int state[16]; u64int bstate[8]; }; uchar buf[256]; From bb1860d02bd450716127149eebe7ab1e618e0b93 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 05:24:52 +0300 Subject: [PATCH 12/21] libmemdraw/draw.c: fix misleading indentation --- libmemdraw/draw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libmemdraw/draw.c b/libmemdraw/draw.c index 7c6f486..c569a74 100644 --- a/libmemdraw/draw.c +++ b/libmemdraw/draw.c @@ -101,7 +101,7 @@ _memimagedrawsetup(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage if(mask == nil) mask = memopaque; -DBG print("memimagedraw %p/%luX %R @ %p %p/%luX %P %p/%luX %P... ", dst, dst->chan, r, dst->data->bdata, src, src->chan, p0, mask, mask->chan, p1); +DBG print("memimagedraw %p/%luX %R @ %p %p/%luX %P %p/%luX %P... ", dst, dst->chan, r, dst->data->bdata, src, src->chan, p0, mask, mask->chan, p1); if(drawclip(dst, &r, src, &p0, mask, &p1, &par.sr, &par.mr) == 0){ // if(drawdebug) @@ -776,9 +776,9 @@ DBG print("["); bmask = rdmask(&mpar, mpar.bufbase, masky); DBG print("]\n"); bdst = rddst(&dpar, dpar.bufbase, dsty); -DBG dumpbuf("src", bsrc, dx); -DBG dumpbuf("mask", bmask, dx); -DBG dumpbuf("dst", bdst, dx); +DBG dumpbuf("src", bsrc, dx); +DBG dumpbuf("mask", bmask, dx); +DBG dumpbuf("dst", bdst, dx); bdst = calc(bdst, bsrc, bmask, dx, isgrey, op); wrdst(&dpar, dpar.bytermin+dsty*dpar.bwidth, bdst); } From 9e72b1f4c8b36cdec3215135c84a4563b065771d Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 05:27:02 +0300 Subject: [PATCH 13/21] libmemlayer/draw.c: fix misleading indentation --- libmemlayer/draw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libmemlayer/draw.c b/libmemlayer/draw.c index c352a0b..d6c6c25 100644 --- a/libmemlayer/draw.c +++ b/libmemlayer/draw.c @@ -64,7 +64,8 @@ memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Poi mask = memopaque; if(mask->layer){ -if(drawdebug) iprint("mask->layer != nil\n"); + if(drawdebug) + iprint("mask->layer != nil\n"); return; /* too hard, at least for now */ } @@ -75,7 +76,8 @@ if(drawdebug) iprint("mask->layer != nil\n"); } if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){ -if(drawdebug) iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr); + if(drawdebug) + iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr); return; } From 17c6c70a9f145a60c171bd13c4f6df580813723a Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:26:42 +0300 Subject: [PATCH 14/21] gui-win32/screen.c: use char* for clipboard functions --- gui-win32/screen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gui-win32/screen.c b/gui-win32/screen.c index c7ba8b2..5e816d6 100644 --- a/gui-win32/screen.c +++ b/gui-win32/screen.c @@ -570,12 +570,12 @@ setcolor(ulong index, ulong red, ulong green, ulong blue) } -uchar* +char* clipreadunicode(HANDLE h) { Rune16 *p; int n; - uchar *q; + char *q; p = GlobalLock(h); n = rune16nlen(p, runes16len(p)+1); @@ -586,10 +586,10 @@ clipreadunicode(HANDLE h) return q; } -uchar * +char * clipreadutf(HANDLE h) { - uchar *p; + char *p; p = GlobalLock(h); p = strdup(p); @@ -602,7 +602,7 @@ char* clipread(void) { HANDLE h; - uchar *p; + char *p; if(!OpenClipboard(window)) { oserror(); From 7e290c00c0cebedd915b972519a0ddba4673249b Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:30:38 +0300 Subject: [PATCH 15/21] gui-win32/screen.c: remove unused variable --- gui-win32/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui-win32/screen.c b/gui-win32/screen.c index 5e816d6..e935e2e 100644 --- a/gui-win32/screen.c +++ b/gui-win32/screen.c @@ -626,7 +626,7 @@ int clipwrite(char *buf) { HANDLE h; - char *p, *e; + char *p; Rune16 *rp; int n = strlen(buf); From bc5e0a27bf142c1eb641bcd31538471276ac4ca7 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:46:35 +0300 Subject: [PATCH 16/21] gui-win32/screen.c: add parentheses in window style --- gui-win32/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui-win32/screen.c b/gui-win32/screen.c index e935e2e..0364545 100644 --- a/gui-win32/screen.c +++ b/gui-win32/screen.c @@ -41,7 +41,7 @@ static Rendez rend; Point ZP; uint windowStyle; -const uint BORDERLESS = WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME | WS_SYSMENU | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_VISIBLE | WS_POPUP ^ WS_MINIMIZE | WS_MAXIMIZE; +const uint BORDERLESS = (WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME | WS_SYSMENU | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_VISIBLE) | (WS_POPUP ^ WS_MINIMIZE) | WS_MAXIMIZE; static int isready(void*a) From 99cc3c6e28178d323cb09c7110229ca5e9618734 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:48:17 +0300 Subject: [PATCH 17/21] gui-win32/r16.c: add parentheses around assignment used as truth value --- gui-win32/r16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui-win32/r16.c b/gui-win32/r16.c index 9de6783..2add199 100644 --- a/gui-win32/r16.c +++ b/gui-win32/r16.c @@ -59,7 +59,7 @@ runes16toutf(char *p, Rune16 *r, int nc) op = p; ep = p + nc; - while(c = *r++) { + while((c = *r++)) { n = 1; if(c >= Runeself) n = runelen(c); From b7b127fa806e5e9bb110a5febbbd3add0d7d2c43 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:52:12 +0300 Subject: [PATCH 18/21] gui-win32/r16.h: define smalloc --- gui-win32/r16.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gui-win32/r16.h b/gui-win32/r16.h index ea4ee28..2c40026 100644 --- a/gui-win32/r16.h +++ b/gui-win32/r16.h @@ -9,3 +9,4 @@ Rune16* runes16dup(Rune16*); Rune16* utftorunes16(Rune16*, char*, int); char* runes16toutf(char*, Rune16*, int); int runes16cmp(Rune16*, Rune16*); +void* smalloc(ulong); From 4f896ab7d10e6e14bf9bba27e63ad6d6f115627c Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:53:50 +0300 Subject: [PATCH 19/21] libc/runevsmprint.c: don't use pointer after realloc --- libc/runevsmprint.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libc/runevsmprint.c b/libc/runevsmprint.c index 6d391e2..7643c68 100644 --- a/libc/runevsmprint.c +++ b/libc/runevsmprint.c @@ -6,23 +6,24 @@ static int runeFmtStrFlush(Fmt *f) { Rune *s; - int n; + int n, d; if(f->start == nil) return 0; n = (uintptr)f->farg; n *= 2; - s = (Rune*)f->start; - f->start = realloc(s, sizeof(Rune)*n); - if(f->start == nil){ + d = (Rune*)f->to - (Rune*)f->start; + s = realloc(f->start, sizeof(Rune)*n); + if(s == nil){ f->farg = nil; f->to = nil; f->stop = nil; - free(s); + free(f->start); return 0; } + f->start = s; f->farg = (void*)(uintptr)n; - f->to = (Rune*)f->start + ((Rune*)f->to - s); + f->to = (Rune*)f->start + d; f->stop = (Rune*)f->start + n - 1; return 1; } From 0122bbe88984c06844e7a31b7cc6c73df8879595 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 07:59:45 +0300 Subject: [PATCH 20/21] libc/strtod.c: include ctype.h --- libc/strtod.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libc/strtod.c b/libc/strtod.c index a48abe5..f3b1637 100644 --- a/libc/strtod.c +++ b/libc/strtod.c @@ -1,5 +1,6 @@ #include #include +#include #include "fmtdef.h" static ulong From 1ea3f719ae55dc0b64c1921385cc2eb743310a45 Mon Sep 17 00:00:00 2001 From: Adrian Grigore Date: Tue, 9 Jul 2024 08:09:16 +0300 Subject: [PATCH 21/21] libc/vsmprint.c: don't use pointer after realloc --- libc/vsmprint.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libc/vsmprint.c b/libc/vsmprint.c index df5abe4..27d08ac 100644 --- a/libc/vsmprint.c +++ b/libc/vsmprint.c @@ -6,23 +6,24 @@ static int fmtStrFlush(Fmt *f) { char *s; - int n; + int n, d; if(f->start == nil) return 0; n = (uintptr)f->farg; n *= 2; - s = (char*)f->start; - f->start = realloc(s, n); - if(f->start == nil){ + d = (char*)f->to - (char*)f->start; + s = realloc(f->start, n); + if(s == nil){ f->farg = nil; f->to = nil; f->stop = nil; - free(s); + free(f->start); return 0; } + f->start = s; f->farg = (void*)(uintptr)n; - f->to = (char*)f->start + ((char*)f->to - s); + f->to = (char*)f->start + d; f->stop = (char*)f->start + n - 1; return 1; }