The appended patch (against head) syncs FreeBSD's arc4random(3) implementation with that of OpenBSD, in particular Markus Friedl's latest work: It replaces RC4 in arc4random() with the more secure stream cipher ChaCha20 (http://cr.yp.to/chacha.html) by Bernstein. It's about as fast as the original code. The main difference is that it creates a 1024 byte key stream and returns randomness from this buffer before rekeying and refilling the buffer. The choice of ChaCha and the overall design is heavily influenced by Nick Mathewson's libottery. References: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/ https://github.com/nmathewson/libottery Fix: Property changes on: chacha_private.h ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property--gS8BRH9XZRry02ICHLpqlSnC1tkd3KLrfmBxPByaOswakocF Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" Index: arc4random.c =================================================================== --- arc4random.c (revision 256022) +++ arc4random.c (working copy) @@ -1,8 +1,9 @@ -/* $OpenBSD: arc4random.c,v 1.22 2010/12/22 08:23:42 otto Exp $ */ +/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus 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> @@ -36,6 +29,7 @@ #include <fcntl.h> #include <limits.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/param.h> @@ -46,6 +40,9 @@ #include "libc_private.h" #include "un-namespace.h" +#define KEYSTREAM_ONLY +#include "chacha_private.h" + #ifdef __GNUC__ #define inline __inline #else /* !__GNUC__ */ @@ -52,16 +49,13 @@ #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 KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) #define _ARC4_LOCK() \ do { \ if (__isthreaded) \ @@ -75,46 +69,28 @@ } while (0) 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[RSBUFSZ]; /* keystream blocks */ +static size_t rs_have; /* valid bytes at end of rs_buf */ +static size_t rs_count; /* bytes till reseed */ 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 _rs_rekey(u_char *dat, size_t datlen); static inline void -arc4_init(void) +_rs_init(u_char *buf, size_t n) { - int n; - - for (n = 0; n < 256; n++) - rs.s[n] = n; - rs.i = 0; - rs.j = 0; + if (n < KEYSZ + IVSZ) + return; + chacha_keysetup(&rs, buf, KEYSZ * 8, 0); + chacha_ivsetup(&rs, buf + KEYSZ); } -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; -} - static size_t -arc4_sysctl(u_char *buf, size_t size) +_rs_sysctl(u_char *buf, size_t size) { int mib[2]; size_t len, done; @@ -136,26 +112,22 @@ } static void -arc4_stir(void) +_rs_stir(void) { - int done, fd, i; + int done, fd; struct { struct timeval tv; pid_t pid; - u_char rnd[KEYSIZE]; + u_char rnd[KEYSZ + IVSZ]; } rdat; - if (!rs_initialized) { - arc4_init(); - rs_initialized = 1; - } done = 0; - if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE) + if (_rs_sysctl((u_char *)&rdat, KEYSZ + IVSZ) == KEYSZ + IVSZ) done = 1; if (!done) { fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { - if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) + if (_read(fd, &rdat, KEYSZ + IVSZ) == KEYSZ + IVSZ) done = 1; (void)_close(fd); } @@ -166,52 +138,85 @@ /* We'll just take whatever was on the stack too... */ } - arc4_addrandom((u_char *)&rdat, KEYSIZE); + if (!rs_initialized) { + rs_initialized = 1; + _rs_init((u_char *)&rdat, KEYSZ + IVSZ); + } else + _rs_rekey((u_char *)&rdat, KEYSZ + IVSZ); + memset((u_char *)&rdat, 0, sizeof(rdat)); - /* - * 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; + /* invalidate rs_buf */ + rs_have = 0; + memset(rs_buf, 0, RSBUFSZ); + + 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 void +_rs_rekey(u_char *dat, size_t datlen) +{ +#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; + + 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_int8_t -arc4_getbyte(void) +static inline void +_rs_random_buf(void *_buf, size_t n) { - u_int8_t si, sj; + u_char *buf = (u_char *)_buf; + size_t 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]); + _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); + } } -static inline u_int32_t -arc4_getword(void) +static inline void +_rs_random_u32(u_int32_t *val) { - u_int32_t val; - val = arc4_getbyte() << 24; - val |= arc4_getbyte() << 16; - val |= arc4_getbyte() << 8; - val |= arc4_getbyte(); - return val; + _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; } void @@ -218,7 +223,7 @@ arc4random_stir(void) { _ARC4_LOCK(); - arc4_stir(); + _rs_stir(); _ARC4_UNLOCK(); } @@ -225,10 +230,17 @@ void arc4random_addrandom(u_char *dat, int datlen) { + int m; + _ARC4_LOCK(); if (!rs_initialized) - arc4_stir(); - arc4_addrandom(dat, datlen); + _rs_stir(); + while (datlen > 0) { + m = MIN(datlen, KEYSZ + IVSZ); + _rs_rekey(dat, m); + dat += m; + datlen -= m; + } _ARC4_UNLOCK(); } @@ -236,25 +248,18 @@ 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 +281,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 @@ -321,5 +317,6 @@ v /= iter; printf("%qd cycles\n", v); + exit(0); } #endif Index: chacha_private.h =================================================================== --- chacha_private.h (revision 0) +++ chacha_private.h (working copy) @@ -0,0 +1,220 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +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; + u8 tmp[64]; + 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 + } +}
Responsible Changed From-To: freebsd-bugs->secteam Over to maintainer(s).
A slightly different version is proposed here https://github.com/HardenedBSD/hardenedBSD/blob/efe9fbb405647b6e223a621a6ff4c36a6d237071/lib/libc/gen/arc4random.c with you can notice use mmap INHERIT_ZERO flag which does not exist yet https://github.com/HardenedBSD/hardenedBSD/commit/a222f4ff2a22b7b937dde3756dcc3633ca1e9eb9
Created attachment 147975 [details] Proposed patch
Created attachment 147976 [details] Proposed patch
Created attachment 149068 [details] Updated patch This represents the lastest change.
Created attachment 149507 [details] Updated patch
Please ignore this patch until the VM part not cleaned up.
I'll take a look at this. Note that this is libc's arc4random(3), not libkern's arc4random(9), which is completely different code. It would be a good idea to merge the two.
(In reply to Dag-Erling Smørgrav from comment #8) Please note that we need https://reviews.freebsd.org/D427 landed.
Holy FSM, I thought that had been committed ages ago. What's the holdup?
There was also forkdepth() proposed (https://people.freebsd.org/~kib/misc/forkdepth.1.patch). Does that approach have any downsides compared to mmap with INHERIT_ZERO? To me, forkdepth() looks like the cleaner API.
VDSOs are orthogonal to INHERIT_ZERO.
A commit references this bug: Author: delphij Date: Tue Mar 14 17:10:43 UTC 2017 New revision: 315272 URL: https://svnweb.freebsd.org/changeset/base/315272 Log: Implement INHERIT_ZERO for minherit(2). INHERIT_ZERO is an OpenBSD feature. When a page is marked as such, it would be zeroed upon fork(). This would be used in new arc4random(3) functions. PR: 182610 Reviewed by: kib (earlier version) MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D427 Changes: head/lib/libc/sys/minherit.2 head/sys/sys/mman.h head/sys/vm/vm.h head/sys/vm/vm_map.c
(In reply to Dag-Erling Smørgrav from comment #10) There were some discussion and I got distracted from this by some other work :( By the way, I actually have some Chacha20 stuff on github at https://github.com/freebsd/freebsd/compare/master...delphij:featurefork/chacha20 back in 2014, and some features may still be interesting (e.g. multithread support; compatibility shims for arc4random_stir()), so feel free to take them if needed.
A commit references this bug: Author: delphij Date: Wed May 31 05:10:03 UTC 2017 New revision: 319277 URL: https://svnweb.freebsd.org/changeset/base/319277 Log: MFC r315272, r315370 r315272: Implement INHERIT_ZERO for minherit(2). INHERIT_ZERO is an OpenBSD feature. When a page is marked as such, it would be zeroed upon fork(). This would be used in new arc4random(3) functions. PR: 182610 Reviewed by: kib (earlier version) Differential Revision: https://reviews.freebsd.org/D427 r315370: The adj_free and max_free values of new_entry will be calculated and assigned by subsequent vm_map_entry_link(), therefore, remove the pointless copying. Submitted by: alc Changes: _U stable/11/ stable/11/lib/libc/sys/minherit.2 stable/11/sys/sys/mman.h stable/11/sys/vm/vm.h stable/11/sys/vm/vm_map.c
A commit references this bug: Author: delphij Date: Wed May 31 05:11:28 UTC 2017 New revision: 319278 URL: https://svnweb.freebsd.org/changeset/base/319278 Log: MFC r315272, r315370 r315272: Implement INHERIT_ZERO for minherit(2). INHERIT_ZERO is an OpenBSD feature. When a page is marked as such, it would be zeroed upon fork(). This would be used in new arc4random(3) functions. PR: 182610 Reviewed by: kib (earlier version) Differential Revision: https://reviews.freebsd.org/D427 r315370: The adj_free and max_free values of new_entry will be calculated and assigned by subsequent vm_map_entry_link(), therefore, remove the pointless copying. Submitted by: alc Changes: _U stable/10/ stable/10/lib/libc/sys/minherit.2 stable/10/sys/sys/mman.h stable/10/sys/vm/vm.h stable/10/sys/vm/vm_map.c
Created attachment 189567 [details] patch to make userspace arc4random fork safe Any updates on this? In the meantime I've been using this patch that at least makes arc4random(3) fork safe.
Created attachment 196272 [details] Proposed patch updated to latest OpenBSD version Proposed patch. I'll create a review for this as well.
(In reply to Xin LI from comment #18) https://reviews.freebsd.org/D16760
A commit references this bug: Author: delphij Date: Sat Aug 18 06:20:46 UTC 2018 New revision: 337997 URL: https://svnweb.freebsd.org/changeset/base/337997 Log: Split arc4random_uniform into it's own file and sync with OpenBSD. PR: 182610 Obtained from: OpenBSD MFC after: 2 weeks Changes: head/lib/libc/gen/Makefile.inc head/lib/libc/gen/arc4random.c head/lib/libc/gen/arc4random_uniform.c
Created attachment 196337 [details] Folded chacha20 implementation with the kernel one and various other fixes
Created attachment 196342 [details] Remove uses of arc4random_addrandom too and remove manual pages for deprecated interfaces
A commit references this bug: Author: delphij Date: Sun Aug 19 17:40:53 UTC 2018 New revision: 338059 URL: https://svnweb.freebsd.org/changeset/base/338059 Log: Update userland arc4random() with OpenBSD's Chacha20 based arc4random(). ObsoleteFiles.inc: Remove manual pages for arc4random_addrandom(3) and arc4random_stir(3). contrib/ntp/lib/isc/random.c: contrib/ntp/sntp/libevent/evutil_rand.c: Eliminate in-tree usage of arc4random_addrandom(). crypto/heimdal/lib/roken/rand.c: crypto/openssh/config.h: Eliminate in-tree usage of arc4random_stir(). include/stdlib.h: Remove arc4random_stir() and arc4random_addrandom() prototypes, provide temporary shims for transistion period. lib/libc/gen/Makefile.inc: Hook arc4random-compat.c to build, add hint for Chacha20 source for kernel, and remove arc4random_addrandom(3) and arc4random_stir(3) links. lib/libc/gen/arc4random.c: Adopt OpenBSD arc4random.c,v 1.54 with bare minimum changes, use the sys/crypto/chacha20 implementation of keystream. lib/libc/gen/Symbol.map: Remove arc4random_stir and arc4random_addrandom interfaces. lib/libc/gen/arc4random.h: Adopt OpenBSD arc4random.h,v 1.4 but provide _ARC4_LOCK of our own. lib/libc/gen/arc4random.3: Adopt OpenBSD arc4random.3,v 1.35 but keep FreeBSD r114444 and r118247. lib/libc/gen/arc4random-compat.c: Compatibility shims for arc4random_stir and arc4random_addrandom functions to preserve ABI. Log once when called but do nothing otherwise. lib/libc/gen/getentropy.c: lib/libc/include/libc_private.h: Fold __arc4_sysctl into getentropy.c (renamed to arnd_sysctl). Remove from libc_private.h as a result. sys/crypto/chacha20/chacha.c: sys/crypto/chacha20/chacha.h: Make it possible to use the kernel implementation in libc. PR: 182610 Reviewed by: cem, markm Obtained from: OpenBSD Relnotes: yes Differential Revision: https://reviews.freebsd.org/D16760 Changes: head/ObsoleteFiles.inc head/contrib/ntp/lib/isc/random.c head/contrib/ntp/sntp/libevent/evutil_rand.c head/crypto/heimdal/lib/roken/rand.c head/crypto/openssh/config.h head/include/stdlib.h head/lib/libc/gen/Makefile.inc head/lib/libc/gen/Symbol.map head/lib/libc/gen/arc4random-compat.c head/lib/libc/gen/arc4random.3 head/lib/libc/gen/arc4random.c head/lib/libc/gen/arc4random.h head/lib/libc/gen/getentropy.c head/lib/libc/include/libc_private.h head/sys/crypto/chacha20/chacha.c head/sys/crypto/chacha20/chacha.h