Index: include/Makefile =================================================================== RCS file: /cvs/src/include/Makefile,v retrieving revision 1.202 diff -u -p -r1.202 Makefile --- include/Makefile 23 Jul 2015 06:04:12 -0000 1.202 +++ include/Makefile 5 Aug 2015 23:56:44 -0000 @@ -9,7 +9,7 @@ .include -FILES= a.out.h ar.h asr.h assert.h bitstring.h blf.h bsd_auth.h \ +FILES= a.out.h ar.h asr.h assert.h bitstring.h blf.h bsd_auth.h chacha.h \ complex.h cpio.h ctype.h curses.h db.h dbm.h dirent.h disktab.h \ dlfcn.h elf_abi.h err.h errno.h fenv.h float.h fnmatch.h fstab.h fts.h \ ftw.h getopt.h glob.h grp.h ifaddrs.h inttypes.h iso646.h kvm.h \ Index: lib/libc/crypt/Makefile.inc =================================================================== RCS file: /cvs/src/lib/libc/crypt/Makefile.inc,v retrieving revision 1.26 diff -u -p -r1.26 Makefile.inc --- lib/libc/crypt/Makefile.inc 8 Dec 2014 20:46:04 -0000 1.26 +++ lib/libc/crypt/Makefile.inc 5 Aug 2015 23:56:45 -0000 @@ -3,7 +3,7 @@ .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/crypt ${LIBCSRCDIR}/crypt SRCS+= crypt.c cryptutil.c arc4random.c arc4random_uniform.c \ - blowfish.c bcrypt.c + blowfish.c bcrypt.c chacha.c MAN+= crypt.3 crypt_checkpass.3 blowfish.3 arc4random.3 MLINKS+=crypt.3 bcrypt_gensalt.3 crypt.3 bcrypt.3 Index: lib/libc/crypt/arc4random.c =================================================================== RCS file: /cvs/src/lib/libc/crypt/arc4random.c,v retrieving revision 1.52 diff -u -p -r1.52 arc4random.c --- lib/libc/crypt/arc4random.c 16 Jan 2015 16:48:51 -0000 1.52 +++ lib/libc/crypt/arc4random.c 5 Aug 2015 23:56:45 -0000 @@ -30,12 +30,10 @@ #include #include #include +#include #include #include -#define KEYSTREAM_ONLY -#include "chacha_private.h" - #define min(a, b) ((a) < (b) ? (a) : (b)) #ifdef __GNUC__ #define inline __inline @@ -43,9 +41,9 @@ #define inline #endif /* !__GNUC__ */ -#define KEYSZ 32 -#define IVSZ 8 -#define BLOCKSZ 64 +#define KEYSZ CHACHA_256KEY_LEN +#define IVSZ CHACHA_IV_LEN +#define BLOCKSZ CHACHA_BLOCK_LEN #define RSBUFSZ (16*BLOCKSZ) /* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ @@ -69,6 +67,11 @@ static inline void _rs_rekey(u_char *dat static inline void _rs_init(u_char *buf, size_t n) { + struct { + chacha_256key key; + chacha_iv iv; + } *b; + if (n < KEYSZ + IVSZ) return; @@ -77,8 +80,9 @@ _rs_init(u_char *buf, size_t n) abort(); } - chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0); - chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); + b = (void *)buf; + chacha_256key_setup(&rsx->rs_chacha, &b->key); + chacha_iv_setup(&rsx->rs_chacha, &b->iv, 0); } static void @@ -117,12 +121,8 @@ _rs_stir_if_needed(size_t len) static inline void _rs_rekey(u_char *dat, size_t datlen) { -#ifndef KEYSTREAM_ONLY - memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); -#endif /* fill rs_buf with the keystream */ - chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, - rsx->rs_buf, sizeof(rsx->rs_buf)); + chacha_stream(&rsx->rs_chacha, rsx->rs_buf, sizeof(rsx->rs_buf)); /* mix in optional user provided data */ if (dat) { size_t i, m; Index: lib/libc/crypt/chacha.c =================================================================== RCS file: lib/libc/crypt/chacha.c diff -N lib/libc/crypt/chacha.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/crypt/chacha.c 5 Aug 2015 23:56:45 -0000 @@ -0,0 +1,217 @@ +/* $OpenBSD$ */ + +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include +#include +#include + +#define U8TO32_LITTLE(p) \ + (((uint32_t)((p)[0]) ) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) do { \ + (p)[0] = (v) ; \ + (p)[1] = (v) >> 8; \ + (p)[2] = (v) >> 16; \ + (p)[3] = (v) >> 24; \ +} while (0) + +#define ROTATE(v, n) ((v) << (n) | ((v) >> (32 - (n)))) + +static void +chacha_key_setup(chacha_ctx *ctx, const uint32_t *c, + const uint32_t *k1, const uint32_t *k2) +{ + ctx->input[0] = letoh32(c[0]); + ctx->input[1] = letoh32(c[1]); + ctx->input[2] = letoh32(c[2]); + ctx->input[3] = letoh32(c[3]); + + ctx->input[4] = letoh32(k1[0]); + ctx->input[5] = letoh32(k1[1]); + ctx->input[6] = letoh32(k1[2]); + ctx->input[7] = letoh32(k1[3]); + + ctx->input[8] = letoh32(k2[0]); + ctx->input[9] = letoh32(k2[1]); + ctx->input[10] = letoh32(k2[2]); + ctx->input[11] = letoh32(k2[3]); +} + +void +chacha_128key_setup(chacha_ctx *ctx, const chacha_128key *key) +{ + static const char tau[16] = "expand 16-byte k"; + + chacha_key_setup(ctx, (uint32_t *)tau, key->k, key->k); +} + +void +chacha_256key_setup(chacha_ctx *ctx, const chacha_256key *key) +{ + static const char sigma[16] = "expand 32-byte k"; + + chacha_key_setup(ctx, (uint32_t *)sigma, key->k, key->k + 4); +} + +void +chacha_iv_setup(chacha_ctx *ctx, const chacha_iv *iv, uint64_t counter) +{ + ctx->input[12] = counter; + ctx->input[13] = counter >> 32; + ctx->input[14] = letoh32(iv->iv[0]); + ctx->input[15] = letoh32(iv->iv[1]); +} + +#define QUARTERROUND(a, b, c, d) do { \ + a += b; d = ROTATE(d ^ a, 16); \ + c += d; b = ROTATE(b ^ c, 12); \ + a += b; d = ROTATE(d ^ a, 8); \ + c += d; b = ROTATE(b ^ c, 7); \ +} while (0) + +static inline void +chacha_round(chacha_ctx *ctx, chacha_ctx *state) +{ + uint32_t *x = state->input; + u_int i; + + *state = *ctx; + + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x[0], x[4], x[8], x[12]); + QUARTERROUND(x[1], x[5], x[9], x[13]); + QUARTERROUND(x[2], x[6], x[10], x[14]); + QUARTERROUND(x[3], x[7], x[11], x[15]); + QUARTERROUND(x[0], x[5], x[10], x[15]); + QUARTERROUND(x[1], x[6], x[11], x[12]); + QUARTERROUND(x[2], x[7], x[8], x[13]); + QUARTERROUND(x[3], x[4], x[9], x[14]); + } + + /* unrolled loop is fast */ + x[0] += ctx->input[0]; + x[1] += ctx->input[1]; + x[2] += ctx->input[2]; + x[3] += ctx->input[3]; + x[4] += ctx->input[4]; + x[5] += ctx->input[5]; + x[6] += ctx->input[6]; + x[7] += ctx->input[7]; + x[8] += ctx->input[8]; + x[9] += ctx->input[9]; + x[10] += ctx->input[10]; + x[11] += ctx->input[11]; + x[12] += ctx->input[12]; + x[13] += ctx->input[13]; + x[14] += ctx->input[14]; + x[15] += ctx->input[15]; + + if (++ctx->input[12] == 0) + ++ctx->input[13]; +} + +static inline void +chacha_xorwr(const chacha_ctx *state, uint8_t *dst, const uint8_t *src) +{ + /* unrolled loop is fast */ + U32TO8_LITTLE(dst, state->input[0] ^ U8TO32_LITTLE(src)); + U32TO8_LITTLE(dst + 4, state->input[1] ^ U8TO32_LITTLE(src + 4)); + U32TO8_LITTLE(dst + 8, state->input[2] ^ U8TO32_LITTLE(src + 8)); + U32TO8_LITTLE(dst + 12, state->input[3] ^ U8TO32_LITTLE(src + 12)); + U32TO8_LITTLE(dst + 16, state->input[4] ^ U8TO32_LITTLE(src + 16)); + U32TO8_LITTLE(dst + 20, state->input[5] ^ U8TO32_LITTLE(src + 20)); + U32TO8_LITTLE(dst + 24, state->input[6] ^ U8TO32_LITTLE(src + 24)); + U32TO8_LITTLE(dst + 28, state->input[7] ^ U8TO32_LITTLE(src + 28)); + U32TO8_LITTLE(dst + 32, state->input[8] ^ U8TO32_LITTLE(src + 32)); + U32TO8_LITTLE(dst + 36, state->input[9] ^ U8TO32_LITTLE(src + 36)); + U32TO8_LITTLE(dst + 40, state->input[10] ^ U8TO32_LITTLE(src + 40)); + U32TO8_LITTLE(dst + 44, state->input[11] ^ U8TO32_LITTLE(src + 44)); + U32TO8_LITTLE(dst + 48, state->input[12] ^ U8TO32_LITTLE(src + 48)); + U32TO8_LITTLE(dst + 52, state->input[13] ^ U8TO32_LITTLE(src + 52)); + U32TO8_LITTLE(dst + 56, state->input[14] ^ U8TO32_LITTLE(src + 56)); + U32TO8_LITTLE(dst + 60, state->input[15] ^ U8TO32_LITTLE(src + 60)); +} + +void +chacha_encrypt(chacha_ctx *ctx, void *d, const void *s, size_t len) +{ + chacha_ctx state; + const uint8_t *src = s; + uint8_t *dst = d; + + if (len == 0) + return; + + while (len >= CHACHA_BLOCK_LEN) { + chacha_round(ctx, &state); + + chacha_xorwr(&state, dst, src); + + dst += CHACHA_BLOCK_LEN; + src += CHACHA_BLOCK_LEN; + len -= CHACHA_BLOCK_LEN; + } + + if (len > 0) { + uint8_t tmp[CHACHA_BLOCK_LEN]; + + memcpy(tmp, src, len); + chacha_encrypt(ctx, tmp, tmp, sizeof(tmp)); + memcpy(dst, tmp, len); + } +} + +static inline void +chacha_wr(const chacha_ctx *state, uint8_t *dst) +{ + U32TO8_LITTLE(dst, state->input[0]); + U32TO8_LITTLE(dst + 4, state->input[1]); + U32TO8_LITTLE(dst + 8, state->input[2]); + U32TO8_LITTLE(dst + 12, state->input[3]); + U32TO8_LITTLE(dst + 16, state->input[4]); + U32TO8_LITTLE(dst + 20, state->input[5]); + U32TO8_LITTLE(dst + 24, state->input[6]); + U32TO8_LITTLE(dst + 28, state->input[7]); + U32TO8_LITTLE(dst + 32, state->input[8]); + U32TO8_LITTLE(dst + 36, state->input[9]); + U32TO8_LITTLE(dst + 40, state->input[10]); + U32TO8_LITTLE(dst + 44, state->input[11]); + U32TO8_LITTLE(dst + 48, state->input[12]); + U32TO8_LITTLE(dst + 52, state->input[13]); + U32TO8_LITTLE(dst + 56, state->input[14]); + U32TO8_LITTLE(dst + 60, state->input[15]); +} + +void +chacha_stream(chacha_ctx *ctx, void *d, size_t len) +{ + chacha_ctx state; + uint8_t *dst = d; + + if (len == 0) + return; + + while (len >= CHACHA_BLOCK_LEN) { + chacha_round(ctx, &state); + + chacha_wr(&state, dst); + + dst += CHACHA_BLOCK_LEN; + len -= CHACHA_BLOCK_LEN; + } + + if (len > 0) { + uint8_t tmp[CHACHA_BLOCK_LEN]; + + chacha_stream(ctx, tmp, sizeof(tmp)); + memcpy(dst, tmp, len); + } +} Index: lib/libc/crypt/chacha_private.h =================================================================== RCS file: lib/libc/crypt/chacha_private.h diff -N lib/libc/crypt/chacha_private.h --- lib/libc/crypt/chacha_private.h 4 Oct 2013 07:02:27 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,222 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ - -typedef unsigned char u8; -typedef unsigned int u32; - -typedef struct -{ - u32 input[16]; /* could be compressed */ -} chacha_ctx; - -#define U8C(v) (v##U) -#define U32C(v) (v##U) - -#define U8V(v) ((u8)(v) & U8C(0xFF)) -#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define U8TO32_LITTLE(p) \ - (((u32)((p)[0]) ) | \ - ((u32)((p)[1]) << 8) | \ - ((u32)((p)[2]) << 16) | \ - ((u32)((p)[3]) << 24)) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#define ROTATE(v,c) (ROTL32(v,c)) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ - a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); - -static const char sigma[16] = "expand 32-byte k"; -static const char tau[16] = "expand 16-byte k"; - -static void -chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) -{ - const char *constants; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); -} - -static void -chacha_ivsetup(chacha_ctx *x,const u8 *iv) -{ - x->input[12] = 0; - x->input[13] = 0; - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); -} - -static void -chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) -{ - u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; - u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - u8 *ctarget = NULL; - u8 tmp[64]; - u_int i; - - if (!bytes) return; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for (;;) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) tmp[i] = m[i]; - m = tmp; - ctarget = c; - c = tmp; - } - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); - -#ifndef KEYSTREAM_ONLY - x0 = XOR(x0,U8TO32_LITTLE(m + 0)); - x1 = XOR(x1,U8TO32_LITTLE(m + 4)); - x2 = XOR(x2,U8TO32_LITTLE(m + 8)); - x3 = XOR(x3,U8TO32_LITTLE(m + 12)); - x4 = XOR(x4,U8TO32_LITTLE(m + 16)); - x5 = XOR(x5,U8TO32_LITTLE(m + 20)); - x6 = XOR(x6,U8TO32_LITTLE(m + 24)); - x7 = XOR(x7,U8TO32_LITTLE(m + 28)); - x8 = XOR(x8,U8TO32_LITTLE(m + 32)); - x9 = XOR(x9,U8TO32_LITTLE(m + 36)); - x10 = XOR(x10,U8TO32_LITTLE(m + 40)); - x11 = XOR(x11,U8TO32_LITTLE(m + 44)); - x12 = XOR(x12,U8TO32_LITTLE(m + 48)); - x13 = XOR(x13,U8TO32_LITTLE(m + 52)); - x14 = XOR(x14,U8TO32_LITTLE(m + 56)); - x15 = XOR(x15,U8TO32_LITTLE(m + 60)); -#endif - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x4); - U32TO8_LITTLE(c + 20,x5); - U32TO8_LITTLE(c + 24,x6); - U32TO8_LITTLE(c + 28,x7); - U32TO8_LITTLE(c + 32,x8); - U32TO8_LITTLE(c + 36,x9); - U32TO8_LITTLE(c + 40,x10); - U32TO8_LITTLE(c + 44,x11); - U32TO8_LITTLE(c + 48,x12); - U32TO8_LITTLE(c + 52,x13); - U32TO8_LITTLE(c + 56,x14); - U32TO8_LITTLE(c + 60,x15); - - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) ctarget[i] = c[i]; - } - x->input[12] = j12; - x->input[13] = j13; - return; - } - bytes -= 64; - c += 64; -#ifndef KEYSTREAM_ONLY - m += 64; -#endif - } -} Index: sbin/ping/ping.c =================================================================== RCS file: /cvs/src/sbin/ping/ping.c,v retrieving revision 1.123 diff -u -p -r1.123 ping.c --- sbin/ping/ping.c 2 May 2015 18:03:37 -0000 1.123 +++ sbin/ping/ping.c 5 Aug 2015 23:56:47 -0000 @@ -74,8 +74,7 @@ #include #include -#define KEYSTREAM_ONLY -#include +#include struct tv64 { u_int64_t tv64_sec; @@ -386,9 +385,9 @@ main(int argc, char *argv[]) if (!(packet = malloc((size_t)packlen))) err(1, "malloc"); if (!(options & F_PINGFILLED) && datalen > sizeof(struct payload)) { - u_int8_t key[32]; - arc4random_buf(key, sizeof(key)); - chacha_keysetup(&fill_stream, key, sizeof(key) * 8, 0); + chacha_256key key; + arc4random_buf(&key, sizeof(key)); + chacha_256key_setup(&fill_stream, &key); } ident = getpid() & 0xFFFF; @@ -654,8 +653,9 @@ pinger(void) if (!(options & F_PINGFILLED) && datalen > sizeof(payload)) { u_int8_t *dp = &outpack[8 + sizeof(payload)]; - chacha_ivsetup(&fill_stream, payload.mac); - chacha_encrypt_bytes(&fill_stream, dp, dp, + chacha_iv_setup(&fill_stream, + (chacha_iv *)payload.mac, 0); + chacha_stream(&fill_stream, dp, datalen - sizeof(payload)); } } @@ -804,8 +804,9 @@ pr_pack(char *buf, int cc, struct sockad cp = (u_char *)&icp->icmp_data[sizeof(struct payload)]; dp = &outpack[8 + sizeof(struct payload)]; if (!(options & F_PINGFILLED)) { - chacha_ivsetup(&fill_stream, payload.mac); - chacha_encrypt_bytes(&fill_stream, dp, dp, + chacha_iv_setup(&fill_stream, + (chacha_iv *)payload.mac, 0); + chacha_stream(&fill_stream, dp, datalen - sizeof(payload)); } for (i = 8 + sizeof(struct payload); Index: sbin/ping6/ping6.c =================================================================== RCS file: /cvs/src/sbin/ping6/ping6.c,v retrieving revision 1.108 diff -u -p -r1.108 ping6.c --- sbin/ping6/ping6.c 2 May 2015 17:19:42 -0000 1.108 +++ sbin/ping6/ping6.c 5 Aug 2015 23:56:47 -0000 @@ -110,6 +110,7 @@ #include #include +#include struct tv64 { u_int64_t tv64_sec; @@ -205,6 +206,7 @@ double tsum = 0.0; /* sum of all times, double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ struct tv64 tv64_offset; /* random offset for time values */ SIPHASH_KEY mac_key; +chacha_ctx fill_stream; /* for node addresses */ u_short naflags; @@ -253,7 +255,7 @@ main(int argc, char *argv[]) struct itimerval itimer; struct sockaddr_in6 from; struct addrinfo hints; - int ch, i, packlen, preload, optval, ret_ga; + int ch, packlen, preload, optval, ret_ga; u_char *datap, *packet; char *e, *target, *ifname = NULL, *gateway = NULL; const char *errstr; @@ -597,9 +599,11 @@ main(int argc, char *argv[]) if (!(packet = malloc(packlen))) err(1, "Unable to allocate packet"); - if (!(options & F_PINGFILLED)) - for (i = ICMP6ECHOLEN; i < packlen; ++i) - *datap++ = i; + if (!(options & F_PINGFILLED)) { + chacha_256key key; + arc4random_buf(&key, sizeof(key)); + chacha_256key_setup(&fill_stream, &key); + } ident = getpid() & 0xFFFF; arc4random_buf(nonce, sizeof(nonce)); @@ -1096,6 +1100,17 @@ pinger(void) memcpy(&outpack[ICMP6ECHOLEN], &payload, sizeof(payload)); + + if (!(options & F_PINGFILLED) && + datalen > sizeof(payload)) { + u_int8_t *dp = &outpack[ICMP6ECHOLEN + + sizeof(payload)]; + + chacha_iv_setup(&fill_stream, + (chacha_iv *)payload.mac, 0); + chacha_stream(&fill_stream, dp, + datalen - sizeof(payload)); + } } cc = ICMP6ECHOLEN + datalen; } @@ -1347,6 +1362,13 @@ pr_pack(u_char *buf, int cc, struct msgh (void)printf(" (%d bytes %s)", abs(delta), delta > 0 ? "extra" : "short"); end = buf + MINIMUM(cc, ICMP6ECHOLEN + datalen); + } + memset(dp, 0, datalen - sizeof(payload)); + if (!(options & F_PINGFILLED)) { + chacha_iv_setup(&fill_stream, + (chacha_iv *)payload.mac, 0); + chacha_stream(&fill_stream, dp, + datalen - sizeof(payload)); } for (i = 8; cp < end; ++i, ++cp, ++dp) { if (*cp != *dp) { Index: sys/crypto/chacha.c =================================================================== RCS file: sys/crypto/chacha.c diff -N sys/crypto/chacha.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/chacha.c 5 Aug 2015 23:56:47 -0000 @@ -0,0 +1,218 @@ +/* $OpenBSD$ */ + +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#include +#include + +#include + +#define U8TO32_LITTLE(p) \ + (((uint32_t)((p)[0]) ) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) do { \ + (p)[0] = (v) ; \ + (p)[1] = (v) >> 8; \ + (p)[2] = (v) >> 16; \ + (p)[3] = (v) >> 24; \ +} while (0) + +#define ROTATE(v, n) ((v) << (n) | ((v) >> (32 - (n)))) + +static void +chacha_key_setup(chacha_ctx *ctx, const uint32_t *c, + const uint32_t *k1, const uint32_t *k2) +{ + ctx->input[0] = lemtoh32(&c[0]); + ctx->input[1] = lemtoh32(&c[1]); + ctx->input[2] = lemtoh32(&c[2]); + ctx->input[3] = lemtoh32(&c[3]); + + ctx->input[4] = lemtoh32(&k1[0]); + ctx->input[5] = lemtoh32(&k1[1]); + ctx->input[6] = lemtoh32(&k1[2]); + ctx->input[7] = lemtoh32(&k1[3]); + + ctx->input[8] = lemtoh32(&k2[0]); + ctx->input[9] = lemtoh32(&k2[1]); + ctx->input[10] = lemtoh32(&k2[2]); + ctx->input[11] = lemtoh32(&k2[3]); +} + +void +chacha_128key_setup(chacha_ctx *ctx, const chacha_128key *key) +{ + static const char tau[16] = "expand 16-byte k"; + + chacha_key_setup(ctx, (uint32_t *)tau, key->k, key->k); +} + +void +chacha_256key_setup(chacha_ctx *ctx, const chacha_256key *key) +{ + static const char sigma[16] = "expand 32-byte k"; + + chacha_key_setup(ctx, (uint32_t *)sigma, key->k, key->k + 4); +} + +void +chacha_iv_setup(chacha_ctx *ctx, const chacha_iv *iv, uint64_t counter) +{ + ctx->input[12] = counter; + ctx->input[13] = counter >> 32; + ctx->input[14] = lemtoh32(&iv->iv[0]); + ctx->input[15] = lemtoh32(&iv->iv[1]); +} + +#define QUARTERROUND(a, b, c, d) do { \ + a += b; d = ROTATE(d ^ a, 16); \ + c += d; b = ROTATE(b ^ c, 12); \ + a += b; d = ROTATE(d ^ a, 8); \ + c += d; b = ROTATE(b ^ c, 7); \ +} while (0) + +static inline void +chacha_round(chacha_ctx *ctx, chacha_ctx *state) +{ + uint32_t *x = state->input; + u_int i; + + *state = *ctx; + + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x[0], x[4], x[8], x[12]); + QUARTERROUND(x[1], x[5], x[9], x[13]); + QUARTERROUND(x[2], x[6], x[10], x[14]); + QUARTERROUND(x[3], x[7], x[11], x[15]); + QUARTERROUND(x[0], x[5], x[10], x[15]); + QUARTERROUND(x[1], x[6], x[11], x[12]); + QUARTERROUND(x[2], x[7], x[8], x[13]); + QUARTERROUND(x[3], x[4], x[9], x[14]); + } + + /* unrolled loop is fast */ + x[0] += ctx->input[0]; + x[1] += ctx->input[1]; + x[2] += ctx->input[2]; + x[3] += ctx->input[3]; + x[4] += ctx->input[4]; + x[5] += ctx->input[5]; + x[6] += ctx->input[6]; + x[7] += ctx->input[7]; + x[8] += ctx->input[8]; + x[9] += ctx->input[9]; + x[10] += ctx->input[10]; + x[11] += ctx->input[11]; + x[12] += ctx->input[12]; + x[13] += ctx->input[13]; + x[14] += ctx->input[14]; + x[15] += ctx->input[15]; + + if (++ctx->input[12] == 0) + ++ctx->input[13]; +} + +static inline void +chacha_xorwr(const chacha_ctx *state, uint8_t *dst, const uint8_t *src) +{ + /* unrolled loop is fast */ + U32TO8_LITTLE(dst, state->input[0] ^ U8TO32_LITTLE(src)); + U32TO8_LITTLE(dst + 4, state->input[1] ^ U8TO32_LITTLE(src + 4)); + U32TO8_LITTLE(dst + 8, state->input[2] ^ U8TO32_LITTLE(src + 8)); + U32TO8_LITTLE(dst + 12, state->input[3] ^ U8TO32_LITTLE(src + 12)); + U32TO8_LITTLE(dst + 16, state->input[4] ^ U8TO32_LITTLE(src + 16)); + U32TO8_LITTLE(dst + 20, state->input[5] ^ U8TO32_LITTLE(src + 20)); + U32TO8_LITTLE(dst + 24, state->input[6] ^ U8TO32_LITTLE(src + 24)); + U32TO8_LITTLE(dst + 28, state->input[7] ^ U8TO32_LITTLE(src + 28)); + U32TO8_LITTLE(dst + 32, state->input[8] ^ U8TO32_LITTLE(src + 32)); + U32TO8_LITTLE(dst + 36, state->input[9] ^ U8TO32_LITTLE(src + 36)); + U32TO8_LITTLE(dst + 40, state->input[10] ^ U8TO32_LITTLE(src + 40)); + U32TO8_LITTLE(dst + 44, state->input[11] ^ U8TO32_LITTLE(src + 44)); + U32TO8_LITTLE(dst + 48, state->input[12] ^ U8TO32_LITTLE(src + 48)); + U32TO8_LITTLE(dst + 52, state->input[13] ^ U8TO32_LITTLE(src + 52)); + U32TO8_LITTLE(dst + 56, state->input[14] ^ U8TO32_LITTLE(src + 56)); + U32TO8_LITTLE(dst + 60, state->input[15] ^ U8TO32_LITTLE(src + 60)); +} + +void +chacha_encrypt(chacha_ctx *ctx, void *d, const void *s, size_t len) +{ + chacha_ctx state; + const uint8_t *src = s; + uint8_t *dst = d; + + if (len == 0) + return; + + while (len >= CHACHA_BLOCK_LEN) { + chacha_round(ctx, &state); + + chacha_xorwr(&state, dst, src); + + dst += CHACHA_BLOCK_LEN; + src += CHACHA_BLOCK_LEN; + len -= CHACHA_BLOCK_LEN; + } + + if (len > 0) { + uint8_t tmp[CHACHA_BLOCK_LEN]; + + memcpy(tmp, src, len); + chacha_encrypt(ctx, tmp, tmp, sizeof(tmp)); + memcpy(dst, tmp, len); + } +} + +static inline void +chacha_wr(const chacha_ctx *state, uint8_t *dst) +{ + U32TO8_LITTLE(dst, state->input[0]); + U32TO8_LITTLE(dst + 4, state->input[1]); + U32TO8_LITTLE(dst + 8, state->input[2]); + U32TO8_LITTLE(dst + 12, state->input[3]); + U32TO8_LITTLE(dst + 16, state->input[4]); + U32TO8_LITTLE(dst + 20, state->input[5]); + U32TO8_LITTLE(dst + 24, state->input[6]); + U32TO8_LITTLE(dst + 28, state->input[7]); + U32TO8_LITTLE(dst + 32, state->input[8]); + U32TO8_LITTLE(dst + 36, state->input[9]); + U32TO8_LITTLE(dst + 40, state->input[10]); + U32TO8_LITTLE(dst + 44, state->input[11]); + U32TO8_LITTLE(dst + 48, state->input[12]); + U32TO8_LITTLE(dst + 52, state->input[13]); + U32TO8_LITTLE(dst + 56, state->input[14]); + U32TO8_LITTLE(dst + 60, state->input[15]); +} + +void +chacha_stream(chacha_ctx *ctx, void *d, size_t len) +{ + chacha_ctx state; + uint8_t *dst = d; + + if (len == 0) + return; + + while (len >= CHACHA_BLOCK_LEN) { + chacha_round(ctx, &state); + + chacha_wr(&state, dst); + + dst += CHACHA_BLOCK_LEN; + len -= CHACHA_BLOCK_LEN; + } + + if (len > 0) { + uint8_t tmp[CHACHA_BLOCK_LEN]; + + chacha_stream(ctx, tmp, sizeof(tmp)); + memcpy(dst, tmp, len); + } +} Index: sys/crypto/chacha.h =================================================================== RCS file: sys/crypto/chacha.h diff -N sys/crypto/chacha.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/chacha.h 5 Aug 2015 23:56:47 -0000 @@ -0,0 +1,41 @@ +/* $OpenBSD$ */ + +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +#ifndef _CHACHA_H_ +#define _CHACHA_H_ + +typedef struct { + uint32_t input[16]; /* could be compressed */ +} chacha_ctx; + +typedef struct { + uint32_t k[4]; +} chacha_128key; + +typedef struct { + uint32_t k[8]; +} chacha_256key; + +typedef struct { + uint32_t iv[2]; +} chacha_iv; + +#define CHACHA_128KEY_LEN sizeof(chacha_128key) +#define CHACHA_256KEY_LEN sizeof(chacha_256key) +#define CHACHA_IV_LEN sizeof(chacha_iv) +#define CHACHA_BLOCK_LEN 64 + +void chacha_128key_setup(chacha_ctx *, const chacha_128key *); +void chacha_256key_setup(chacha_ctx *, const chacha_256key *); +void chacha_iv_setup(chacha_ctx *, const chacha_iv *, uint64_t); +void chacha_stream(chacha_ctx *, void *, size_t) + __bounded((__buffer__, 2, 3)); +void chacha_encrypt(chacha_ctx *, void *, const void *, size_t) + __bounded((__buffer__, 2, 4)) __bounded((__buffer__, 3, 4)); + +#endif /* _CHACHA_H_ */ Index: usr.bin/ssh/chacha.c =================================================================== RCS file: usr.bin/ssh/chacha.c diff -N usr.bin/ssh/chacha.c --- usr.bin/ssh/chacha.c 21 Nov 2013 00:45:44 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,217 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -#include "chacha.h" - -/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */ - -typedef unsigned char u8; -typedef unsigned int u32; - -typedef struct chacha_ctx chacha_ctx; - -#define U8C(v) (v##U) -#define U32C(v) (v##U) - -#define U8V(v) ((u8)(v) & U8C(0xFF)) -#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define U8TO32_LITTLE(p) \ - (((u32)((p)[0]) ) | \ - ((u32)((p)[1]) << 8) | \ - ((u32)((p)[2]) << 16) | \ - ((u32)((p)[3]) << 24)) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#define ROTATE(v,c) (ROTL32(v,c)) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ - a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); - -static const char sigma[16] = "expand 32-byte k"; -static const char tau[16] = "expand 16-byte k"; - -void -chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) -{ - const char *constants; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); -} - -void -chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) -{ - x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); - x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); -} - -void -chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) -{ - u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; - u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; - u8 *ctarget = NULL; - u8 tmp[64]; - u_int i; - - if (!bytes) return; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for (;;) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) tmp[i] = m[i]; - m = tmp; - ctarget = c; - c = tmp; - } - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); - - x0 = XOR(x0,U8TO32_LITTLE(m + 0)); - x1 = XOR(x1,U8TO32_LITTLE(m + 4)); - x2 = XOR(x2,U8TO32_LITTLE(m + 8)); - x3 = XOR(x3,U8TO32_LITTLE(m + 12)); - x4 = XOR(x4,U8TO32_LITTLE(m + 16)); - x5 = XOR(x5,U8TO32_LITTLE(m + 20)); - x6 = XOR(x6,U8TO32_LITTLE(m + 24)); - x7 = XOR(x7,U8TO32_LITTLE(m + 28)); - x8 = XOR(x8,U8TO32_LITTLE(m + 32)); - x9 = XOR(x9,U8TO32_LITTLE(m + 36)); - x10 = XOR(x10,U8TO32_LITTLE(m + 40)); - x11 = XOR(x11,U8TO32_LITTLE(m + 44)); - x12 = XOR(x12,U8TO32_LITTLE(m + 48)); - x13 = XOR(x13,U8TO32_LITTLE(m + 52)); - x14 = XOR(x14,U8TO32_LITTLE(m + 56)); - x15 = XOR(x15,U8TO32_LITTLE(m + 60)); - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x4); - U32TO8_LITTLE(c + 20,x5); - U32TO8_LITTLE(c + 24,x6); - U32TO8_LITTLE(c + 28,x7); - U32TO8_LITTLE(c + 32,x8); - U32TO8_LITTLE(c + 36,x9); - U32TO8_LITTLE(c + 40,x10); - U32TO8_LITTLE(c + 44,x11); - U32TO8_LITTLE(c + 48,x12); - U32TO8_LITTLE(c + 52,x13); - U32TO8_LITTLE(c + 56,x14); - U32TO8_LITTLE(c + 60,x15); - - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0;i < bytes;++i) ctarget[i] = c[i]; - } - x->input[12] = j12; - x->input[13] = j13; - return; - } - bytes -= 64; - c += 64; - m += 64; - } -} Index: usr.bin/ssh/chacha.h =================================================================== RCS file: usr.bin/ssh/chacha.h diff -N usr.bin/ssh/chacha.h --- usr.bin/ssh/chacha.h 2 May 2014 03:27:54 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,35 +0,0 @@ -/* $OpenBSD: chacha.h,v 1.3 2014/05/02 03:27:54 djm Exp $ */ - -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -#ifndef CHACHA_H -#define CHACHA_H - -#include - -struct chacha_ctx { - u_int input[16]; -}; - -#define CHACHA_MINKEYLEN 16 -#define CHACHA_NONCELEN 8 -#define CHACHA_CTRLEN 8 -#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) -#define CHACHA_BLOCKLEN 64 - -void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits) - __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); -void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr) - __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN))) - __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN))); -void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m, - u_char *c, u_int bytes) - __attribute__((__bounded__(__buffer__, 2, 4))) - __attribute__((__bounded__(__buffer__, 3, 4))); - -#endif /* CHACHA_H */ - Index: usr.bin/ssh/cipher-chachapoly.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/cipher-chachapoly.c,v retrieving revision 1.7 diff -u -p -r1.7 cipher-chachapoly.c --- usr.bin/ssh/cipher-chachapoly.c 14 Jan 2015 10:24:42 -0000 1.7 +++ usr.bin/ssh/cipher-chachapoly.c 5 Aug 2015 23:56:48 -0000 @@ -29,10 +29,14 @@ int chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen) { - if (keylen != (32 + 32)) /* 2 x 256 bit keys */ + const chacha_256key *keys; + + if (keylen != sizeof(*keys) * 2) /* 2 x 256 bit keys */ return SSH_ERR_INVALID_ARGUMENT; - chacha_keysetup(&ctx->main_ctx, key, 256); - chacha_keysetup(&ctx->header_ctx, key + 32, 256); + + keys = (const chacha_256key *)key; + chacha_256key_setup(&ctx->main_ctx, &keys[0]); + chacha_256key_setup(&ctx->header_ctx, &keys[1]); return 0; } @@ -50,7 +54,6 @@ chachapoly_crypt(struct chachapoly_ctx * const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt) { u_char seqbuf[8]; - const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; int r = SSH_ERR_INTERNAL_ERROR; @@ -58,11 +61,9 @@ chachapoly_crypt(struct chachapoly_ctx * * Run ChaCha20 once to generate the Poly1305 key. The IV is the * packet sequence number. */ - memset(poly_key, 0, sizeof(poly_key)); POKE_U64(seqbuf, seqnr); - chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); - chacha_encrypt_bytes(&ctx->main_ctx, - poly_key, poly_key, sizeof(poly_key)); + chacha_iv_setup(&ctx->main_ctx, (chacha_iv *)seqbuf, 0); + chacha_stream(&ctx->main_ctx, poly_key, sizeof(poly_key)); /* If decrypting, check tag before anything else */ if (!do_encrypt) { @@ -77,14 +78,13 @@ chachapoly_crypt(struct chachapoly_ctx * /* Crypt additional data */ if (aadlen) { - chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); - chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen); + chacha_iv_setup(&ctx->header_ctx, (chacha_iv *)seqbuf, 0); + chacha_encrypt(&ctx->header_ctx, dest, src, aadlen); } /* Set Chacha's block counter to 1 */ - chacha_ivsetup(&ctx->main_ctx, seqbuf, one); - chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen, - dest + aadlen, len); + chacha_iv_setup(&ctx->main_ctx, (chacha_iv *)seqbuf, 1); + chacha_encrypt(&ctx->main_ctx, dest + aadlen, src + aadlen, len); /* If encrypting, calculate and append tag */ if (do_encrypt) { @@ -104,13 +104,15 @@ int chachapoly_get_length(struct chachapoly_ctx *ctx, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { - u_char buf[4], seqbuf[8]; + u_char seqbuf[8]; + u_char buf[4]; if (len < 4) return SSH_ERR_MESSAGE_INCOMPLETE; + POKE_U64(seqbuf, seqnr); - chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); - chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4); + chacha_iv_setup(&ctx->header_ctx, (chacha_iv *)seqbuf, 0); + chacha_encrypt(&ctx->header_ctx, buf, cp, 4); *plenp = PEEK_U32(buf); return 0; } Index: usr.bin/ssh/cipher-chachapoly.h =================================================================== RCS file: /cvs/src/usr.bin/ssh/cipher-chachapoly.h,v retrieving revision 1.4 diff -u -p -r1.4 cipher-chachapoly.h --- usr.bin/ssh/cipher-chachapoly.h 24 Jun 2014 01:13:21 -0000 1.4 +++ usr.bin/ssh/cipher-chachapoly.h 5 Aug 2015 23:56:48 -0000 @@ -19,13 +19,11 @@ #define CHACHA_POLY_AEAD_H #include -#include "chacha.h" +#include #include "poly1305.h" -#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ - struct chachapoly_ctx { - struct chacha_ctx main_ctx, header_ctx; + chacha_ctx main_ctx, header_ctx; }; int chachapoly_init(struct chachapoly_ctx *cpctx, Index: usr.bin/ssh/lib/Makefile =================================================================== RCS file: /cvs/src/usr.bin/ssh/lib/Makefile,v retrieving revision 1.83 diff -u -p -r1.83 Makefile --- usr.bin/ssh/lib/Makefile 3 Mar 2015 21:21:13 -0000 1.83 +++ usr.bin/ssh/lib/Makefile 5 Aug 2015 23:56:48 -0000 @@ -34,7 +34,7 @@ SRCS= ${LIB_SRCS} \ smult_curve25519_ref.c \ kexc25519.c kexc25519c.c kexc25519s.c \ roaming_dummy.c \ - chacha.c poly1305.c cipher-chachapoly.c ssh-ed25519.c hmac.c umac.c + poly1305.c cipher-chachapoly.c ssh-ed25519.c hmac.c umac.c .if (${SSH1:L} == "yes") SRCS+= cipher-3des1.c cipher-bf1.c