Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 May 2014 21:06:33 -0700
From:      Eitan Adler <lists@eitanadler.com>
To:        Adrian Chadd <adrian@freebsd.org>, Mark Murray <markm@freebsd.org>
Cc:        Ted Unangst <tedu@tedunangst.com>, FreeBSD Security Team <secteam@freebsd.org>, "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Re: switch arc4random to chacha
Message-ID:  <CAF6rxg=Ztsyqo-WaupVAkAQN019-jpJgx0ZFE76%2B7tEMqX498w@mail.gmail.com>
In-Reply-To: <CAJ-Vmo=xbVnb7ExGaa-utM1FLe_Z7T6JzCR6TeE=_i-pqfFR%2Bg@mail.gmail.com>
References:  <f0b9ae8e7b2a40a9ab253438261c2c75@tedunangst.com> <CAJ-Vmo=xbVnb7ExGaa-utM1FLe_Z7T6JzCR6TeE=_i-pqfFR%2Bg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
+markm, +secteam

Thanks for the patch,.

Keeping this code in sync is certainly a worthwhile goal.


On 29 May 2014 19:54, Adrian Chadd <adrian@freebsd.org> wrote:
> Hi!
>
> How about running this via the security team here?

He started that process, but mailing a a patch to the mailing list

> Start with Mark Murray (markm@freebsd.org)

I think you mean "keep it on a mailing list, but lets CC someone so it
catches their eye".


Mark any thoughts?

> I'm sure they'll at least want you to fire this up in a VM and test. :P

:)






>
> On 29 May 2014 18:04, Ted Unangst <tedu@tedunangst.com> wrote:
>> This syncs libc arc4random.c with OpenBSD, mostly to change the
>> implementation to ChaCha20.
>>
>> I removed the more complicated seed fetching code and changed it to
>> just sysctl(). A quick check revealed that the FreeBSD kernel supports
>> this for at least five years now. It's much simpler to use code that
>> always works instead of a series of untested fallbacks that are even
>> less likely to work.
>>
>> Also removes the addrandom interface as a useless complication. If the
>> kernel is incapable of properly seeding arc4random, application code
>> can't do any better.
>>
>> Unfortunately, I don't have any FreeBSD systems running at the moment,
>> so I can't make any promises that this will even compile, but it
>> passed the eyeball test.
>>
>> --- arc4random.c.orig   Thu May 29 20:28:49 2014
>> +++ arc4random.c        Thu May 29 20:51:59 2014
>> @@ -1,8 +1,9 @@
>> -/*     $OpenBSD: arc4random.c,v 1.22 2010/12/22 08:23:42 otto Exp $    */
>> +/*     $OpenBSD: arc4random.c,v 1.30 2014/05/06 16:06:33 tedu Exp $    */
>>
>>  /*
>>   * Copyright (c) 1996, David Mazieres <dm@uun.org>
>>   * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
>> + * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
>>   *
>>   * Permission to use, copy, modify, and distribute this software for any
>>   * purpose with or without fee is hereby granted, provided that the above
>> @@ -18,15 +19,7 @@
>>   */
>>
>>  /*
>> - * Arc4 random number generator for OpenBSD.
>> - *
>> - * This code is derived from section 17.1 of Applied Cryptography,
>> - * second edition, which describes a stream cipher allegedly
>> - * compatible with RSA Labs "RC4" cipher (the actual description of
>> - * which is a trade secret).  The same algorithm is used as a stream
>> - * cipher called "arcfour" in Tatu Ylonen's ssh package.
>> - *
>> - * RC4 is a registered trademark of RSA Laboratories.
>> + * ChaCha based random number generator for OpenBSD.
>>   */
>>
>>  #include <sys/cdefs.h>
>> @@ -40,28 +33,24 @@
>>  #include <sys/types.h>
>>  #include <sys/param.h>
>>  #include <sys/sysctl.h>
>> +#include <sys/mman.h>
>>  #include <sys/time.h>
>>  #include <pthread.h>
>>
>>  #include "libc_private.h"
>>  #include "un-namespace.h"
>>
>> +#define KEYSTREAM_ONLY
>> +#include "chacha_private.h"
>> +
>>  #ifdef __GNUC__
>>  #define inline __inline
>>  #else                          /* !__GNUC__ */
>>  #define inline
>>  #endif                         /* !__GNUC__ */
>>
>> -struct arc4_stream {
>> -       u_int8_t i;
>> -       u_int8_t j;
>> -       u_int8_t s[256];
>> -};
>> -
>>  static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
>>
>> -#define        RANDOMDEV       "/dev/random"
>> -#define        KEYSIZE         128
>>  #define        _ARC4_LOCK()                                            \
>>         do {                                                    \
>>                 if (__isthreaded)                               \
>> @@ -74,187 +63,149 @@
>>                         _pthread_mutex_unlock(&arc4random_mtx); \
>>         } while (0)
>>
>> +#define KEYSZ   32
>> +#define IVSZ    8
>> +#define BLOCKSZ 64
>> +#define RSBUFSZ (16*BLOCKSZ)
>>  static int rs_initialized;
>> -static struct arc4_stream rs;
>> -static pid_t arc4_stir_pid;
>> -static int arc4_count;
>> +static pid_t rs_stir_pid;
>> +static chacha_ctx *rs;          /* chacha context for random keystream */
>> +static u_char *rs_buf;          /* keystream blocks */
>> +static size_t rs_have;          /* valid bytes at end of rs_buf */
>> +static size_t rs_count;         /* bytes till reseed */
>>
>> +static inline void _rs_rekey(u_char *dat, size_t datlen);
>> +
>>  extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
>>      void *newp, size_t newlen);
>>
>> -static inline u_int8_t arc4_getbyte(void);
>> -static void arc4_stir(void);
>> -
>>  static inline void
>> -arc4_init(void)
>> +_rs_init(u_char *buf, size_t n)
>>  {
>> -       int     n;
>> +       if (n < KEYSZ + IVSZ)
>> +               return;
>>
>> -       for (n = 0; n < 256; n++)
>> -               rs.s[n] = n;
>> -       rs.i = 0;
>> -       rs.j = 0;
>> -}
>> +       if (rs == NULL && (rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
>> +           MAP_ANON, -1, 0)) == MAP_FAILED)
>> +               abort();
>> +       if (rs_buf == NULL && (rs_buf = mmap(NULL, RSBUFSZ, PROT_READ|PROT_WRITE,
>> +           MAP_ANON, -1, 0)) == MAP_FAILED)
>> +               abort();
>>
>> -static inline void
>> -arc4_addrandom(u_char *dat, int datlen)
>> -{
>> -       int     n;
>> -       u_int8_t si;
>> -
>> -       rs.i--;
>> -       for (n = 0; n < 256; n++) {
>> -               rs.i = (rs.i + 1);
>> -               si = rs.s[rs.i];
>> -               rs.j = (rs.j + si + dat[n % datlen]);
>> -               rs.s[rs.i] = rs.s[rs.j];
>> -               rs.s[rs.j] = si;
>> -       }
>> -       rs.j = rs.i;
>> +       chacha_keysetup(rs, buf, KEYSZ * 8, 0);
>> +       chacha_ivsetup(rs, buf + KEYSZ);
>>  }
>>
>> -static size_t
>> -arc4_sysctl(u_char *buf, size_t size)
>> +static void
>> +_rs_stir(void)
>>  {
>> -       int mib[2];
>> -       size_t len, done;
>> +       int     mib[2];
>> +       size_t  len;
>> +       u_char rnd[KEYSZ + IVSZ];
>>
>>         mib[0] = CTL_KERN;
>>         mib[1] = KERN_ARND;
>> -       done = 0;
>>
>> -       do {
>> -               len = size;
>> -               if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
>> -                       return (done);
>> -               done += len;
>> -               buf += len;
>> -               size -= len;
>> -       } while (size > 0);
>> +       len = sizeof(rnd);
>> +       __sysctl(mib, 2, rnd, &len, NULL, 0);
>>
>> -       return (done);
>> -}
>> -
>> -static void
>> -arc4_stir(void)
>> -{
>> -       int done, fd, i;
>> -       struct {
>> -               struct timeval  tv;
>> -               pid_t           pid;
>> -               u_char          rnd[KEYSIZE];
>> -       } rdat;
>> -
>>         if (!rs_initialized) {
>> -               arc4_init();
>>                 rs_initialized = 1;
>> -       }
>> -       done = 0;
>> -       if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE)
>> -               done = 1;
>> -       if (!done) {
>> -               fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
>> -               if (fd >= 0) {
>> -                       if (_read(fd, &rdat, KEYSIZE) == KEYSIZE)
>> -                               done = 1;
>> -                       (void)_close(fd);
>> -               }
>> -       }
>> -       if (!done) {
>> -               (void)gettimeofday(&rdat.tv, NULL);
>> -               rdat.pid = getpid();
>> -               /* We'll just take whatever was on the stack too... */
>> -       }
>> +               _rs_init(rnd, sizeof(rnd));
>> +       } else
>> +               _rs_rekey(rnd, sizeof(rnd));
>> +       bzero(rnd, sizeof(rnd)); /* explicit_bzero */
>>
>> -       arc4_addrandom((u_char *)&rdat, KEYSIZE);
>> +       /* invalidate rs_buf */
>> +       rs_have = 0;
>> +       memset(rs_buf, 0, RSBUFSZ);
>>
>> -       /*
>> -        * Discard early keystream, as per recommendations in:
>> -        * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
>> -        */
>> -       for (i = 0; i < 1024; i++)
>> -               (void)arc4_getbyte();
>> -       arc4_count = 1600000;
>> +       rs_count = 1600000;
>>  }
>>
>> -static void
>> -arc4_stir_if_needed(void)
>> +static inline void
>> +_rs_stir_if_needed(size_t len)
>>  {
>>         pid_t pid = getpid();
>>
>> -       if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid)
>> -       {
>> -               arc4_stir_pid = pid;
>> -               arc4_stir();
>> -       }
>> +       if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) {
>> +               rs_stir_pid = pid;
>> +               _rs_stir();
>> +       } else
>> +               rs_count -= len;
>>  }
>>
>> -static inline u_int8_t
>> -arc4_getbyte(void)
>> +static inline void
>> +_rs_rekey(u_char *dat, size_t datlen)
>>  {
>> -       u_int8_t si, sj;
>> +#ifndef KEYSTREAM_ONLY
>> +       memset(rs_buf, 0,RSBUFSZ);
>> +#endif
>> +       /* fill rs_buf with the keystream */
>> +       chacha_encrypt_bytes(rs, rs_buf, rs_buf, RSBUFSZ);
>> +       /* mix in optional user provided data */
>> +       if (dat) {
>> +               size_t i, m;
>>
>> -       rs.i = (rs.i + 1);
>> -       si = rs.s[rs.i];
>> -       rs.j = (rs.j + si);
>> -       sj = rs.s[rs.j];
>> -       rs.s[rs.i] = sj;
>> -       rs.s[rs.j] = si;
>> -       return (rs.s[(si + sj) & 0xff]);
>> +               m = MIN(datlen, KEYSZ + IVSZ);
>> +               for (i = 0; i < m; i++)
>> +                       rs_buf[i] ^= dat[i];
>> +       }
>> +       /* immediately reinit for backtracking resistance */
>> +       _rs_init(rs_buf, KEYSZ + IVSZ);
>> +       memset(rs_buf, 0, KEYSZ + IVSZ);
>> +       rs_have = RSBUFSZ - KEYSZ - IVSZ;
>>  }
>>
>> -static inline u_int32_t
>> -arc4_getword(void)
>> +static inline void
>> +_rs_random_buf(void *_buf, size_t n)
>>  {
>> -       u_int32_t val;
>> -       val = arc4_getbyte() << 24;
>> -       val |= arc4_getbyte() << 16;
>> -       val |= arc4_getbyte() << 8;
>> -       val |= arc4_getbyte();
>> -       return val;
>> -}
>> +       u_char *buf = (u_char *)_buf;
>> +       size_t m;
>>
>> -void
>> -arc4random_stir(void)
>> -{
>> -       _ARC4_LOCK();
>> -       arc4_stir();
>> -       _ARC4_UNLOCK();
>> +       _rs_stir_if_needed(n);
>> +       while (n > 0) {
>> +               if (rs_have > 0) {
>> +                       m = MIN(n, rs_have);
>> +                       memcpy(buf, rs_buf + RSBUFSZ - rs_have, m);
>> +                       memset(rs_buf + RSBUFSZ - rs_have, 0, m);
>> +                       buf += m;
>> +                       n -= m;
>> +                       rs_have -= m;
>> +               }
>> +               if (rs_have == 0)
>> +                       _rs_rekey(NULL, 0);
>> +       }
>>  }
>>
>> -void
>> -arc4random_addrandom(u_char *dat, int datlen)
>> +static inline void
>> +_rs_random_u32(u_int32_t *val)
>>  {
>> -       _ARC4_LOCK();
>> -       if (!rs_initialized)
>> -               arc4_stir();
>> -       arc4_addrandom(dat, datlen);
>> -       _ARC4_UNLOCK();
>> +       _rs_stir_if_needed(sizeof(*val));
>> +       if (rs_have < sizeof(*val))
>> +               _rs_rekey(NULL, 0);
>> +       memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val));
>> +       memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val));
>> +       rs_have -= sizeof(*val);
>> +       return;
>>  }
>>
>>  u_int32_t
>>  arc4random(void)
>>  {
>>         u_int32_t val;
>> +
>>         _ARC4_LOCK();
>> -       arc4_count -= 4;
>> -       arc4_stir_if_needed();
>> -       val = arc4_getword();
>> +       _rs_random_u32(&val);
>>         _ARC4_UNLOCK();
>>         return val;
>>  }
>>
>>  void
>> -arc4random_buf(void *_buf, size_t n)
>> +arc4random_buf(void *buf, size_t n)
>>  {
>> -       u_char *buf = (u_char *)_buf;
>>         _ARC4_LOCK();
>> -       arc4_stir_if_needed();
>> -       while (n--) {
>> -               if (--arc4_count <= 0)
>> -                       arc4_stir();
>> -               buf[n] = arc4_getbyte();
>> -       }
>> +       _rs_random_buf(buf, n);
>>         _ARC4_UNLOCK();
>>  }
>>
>> @@ -276,17 +227,8 @@
>>         if (upper_bound < 2)
>>                 return 0;
>>
>> -#if (ULONG_MAX > 0xffffffffUL)
>> -       min = 0x100000000UL % upper_bound;
>> -#else
>> -       /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
>> -       if (upper_bound > 0x80000000)
>> -               min = 1 + ~upper_bound;         /* 2**32 - upper_bound */
>> -       else {
>> -               /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
>> -               min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
>> -       }
>> -#endif
>> +       /* 2**32 % x == (2**32 - x) % x */
>> +       min = -upper_bound % upper_bound;
>>
>>         /*
>>          * This could theoretically loop forever but each retry has
>> @@ -302,24 +244,3 @@
>>
>>         return r % upper_bound;
>>  }
>> -
>> -#if 0
>> -/*-------- Test code for i386 --------*/
>> -#include <stdio.h>
>> -#include <machine/pctr.h>
>> -int
>> -main(int argc, char **argv)
>> -{
>> -       const int iter = 1000000;
>> -       int     i;
>> -       pctrval v;
>> -
>> -       v = rdtsc();
>> -       for (i = 0; i < iter; i++)
>> -               arc4random();
>> -       v = rdtsc() - v;
>> -       v /= iter;
>> -
>> -       printf("%qd cycles\n", v);
>> -}
>> -#endif
>> --- /dev/null   Thu May 29 20:52:04 2014
>> +++ chacha_private.h    Thu May 29 20:40:54 2014
>> @@ -0,0 +1,222 @@
>> +/*
>> +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
>> +  }
>> +}
>> _______________________________________________
>> freebsd-hackers@freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"



-- 
Eitan Adler



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAF6rxg=Ztsyqo-WaupVAkAQN019-jpJgx0ZFE76%2B7tEMqX498w>