From acf8bfba96cfea9c6910e75d123b3bde300053b1 Mon Sep 17 00:00:00 2001 From: Kristaps Dz Date: Sat, 10 Aug 2024 15:37:38 -0700 Subject: [PATCH] Compatibility for arc4random. --- Makefile | 3 +- Makefile.regen | 3 +- compat_arc4random.c | 558 ++++++++++++++++++++++++++++++++++++++++++ compats.c | 560 +++++++++++++++++++++++++++++++++++++++++++ configure | 401 ++++++++++++------------------- configure.in | 401 ++++++++++++------------------- regress/arc4random.c | 9 + 7 files changed, 1445 insertions(+), 490 deletions(-) create mode 100644 compat_arc4random.c create mode 100644 regress/arc4random.c diff --git a/Makefile b/Makefile index 9f1094a..f6238e5 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ REGRESS_CRYPT = regress/crypt REGRESS_B64 = regress/b64_ntop REGRESS_LIB_SOCKET = regress/SOCK_NONBLOCK REGRESS_SCAN_SCALED = regress/scan_scaled -REGRESS_NODEP = regress/blowfish \ +REGRESS_NODEP = regress/arc4random \ + regress/blowfish \ regress/capsicum \ regress/crypt_newhash \ regress/endian \ diff --git a/Makefile.regen b/Makefile.regen index 3a041cd..fa101b8 100644 --- a/Makefile.regen +++ b/Makefile.regen @@ -1,7 +1,8 @@ .PHONY: distcheck VERSION = 0.3.13 -COMPATS = compat_blowfish.c \ +COMPATS = compat_arc4random.c \ + compat_blowfish.c \ compat_crypt_newhash.c \ compat_err.c \ compat_b64_ntop.c \ diff --git a/compat_arc4random.c b/compat_arc4random.c new file mode 100644 index 0000000..6af9a92 --- /dev/null +++ b/compat_arc4random.c @@ -0,0 +1,558 @@ +/* + * chacha-merged.c version 20080118 + * D. J. Bernstein + * Public domain. + */ + +/* $OpenBSD$ */ + +#include + +#define KEYSTREAM_ONLY + +typedef struct +{ + uint32_t input[16]; /* could be compressed */ +} chacha_ctx; + +typedef unsigned char u8; +typedef uint32_t u32; + +#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; + + (void)ivbits; + + 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 + } +} + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * Copyright (c) 2015, Sudhi Herle + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator from OpenBSD. + * + * Made fully portable and thread-safe by Sudhi Herle. + */ + +#if defined(__linux__) || defined(__wasi__) +# define _DEFAULT_SOURCE /* new glibc for getentropy() */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ARC4R_KEYSZ 32 +#define ARC4R_IVSZ 8 +#define ARC4R_BLOCKSZ 64 +#define ARC4R_RSBUFSZ (16*ARC4R_BLOCKSZ) + +// must be a power of 2 +#define REKEY_BASE (1 << 10) + +struct rand_state +{ + size_t rs_have; /* valid bytes at end of rs_buf */ + size_t rs_count; /* bytes till reseed */ + pid_t rs_pid; /* My PID */ + chacha_ctx rs_chacha; /* chacha context for random keystream */ + uint8_t rs_buf[ARC4R_RSBUFSZ]; /* keystream blocks */ +}; +typedef struct rand_state rand_state; + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +static inline void +_rs_init(rand_state* st, uint8_t *buf, size_t n) +{ + assert(n >= (ARC4R_KEYSZ + ARC4R_IVSZ)); + + chacha_keysetup(&st->rs_chacha, buf, ARC4R_KEYSZ * 8, 0); + chacha_ivsetup(&st->rs_chacha, buf + ARC4R_KEYSZ); +} + +static inline void +_rs_rekey(rand_state* st, uint8_t *dat, size_t datlen) +{ + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&st->rs_chacha, st->rs_buf, st->rs_buf, sizeof st->rs_buf); + + /* mix in optional user provided data */ + if (dat) { + size_t m = minimum(datlen, ARC4R_KEYSZ + ARC4R_IVSZ); + for (size_t i = 0; i < m; i++) + st->rs_buf[i] ^= dat[i]; + + memset(dat, 0, datlen); + } + + assert(sizeof(st->rs_buf) > (ARC4R_KEYSZ+ARC4R_IVSZ)); + + /* + * immediately reinit for backtracking resistance: + * We're consuming enough bytes to make a new chacha context (key+iv). + * Thus, we have those many fewer bytes in the entropy buf + */ + _rs_init(st, st->rs_buf, ARC4R_KEYSZ + ARC4R_IVSZ); + memset(st->rs_buf, 0, ARC4R_KEYSZ + ARC4R_IVSZ); + st->rs_have = (sizeof st->rs_buf) - ARC4R_KEYSZ - ARC4R_IVSZ; +} + +static void +_rs_stir(rand_state* st) +{ + uint8_t rnd[ARC4R_KEYSZ + ARC4R_IVSZ]; + size_t rekey_fuzz = 0; + uint8_t *fuzzp = (uint8_t*)&rekey_fuzz; + + + int r = getentropy(rnd, sizeof rnd); + assert(r == 0); + + _rs_rekey(st, rnd, sizeof(rnd)); + + /* invalidate rs_buf */ + st->rs_have = 0; + memset(st->rs_buf, 0, sizeof st->rs_buf); + + chacha_encrypt_bytes(&st->rs_chacha, fuzzp, fuzzp, sizeof rekey_fuzz); + st->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE); +} + +static inline void +_rs_stir_if_needed(rand_state* st, size_t len) +{ + if (st->rs_count <= len) + _rs_stir(st); + + st->rs_count -= len; +} + +// consume 'n' random btyes from the entropy buffer. Return total +// actually consumed. +static inline size_t +_rs_consume(rand_state *rs, uint8_t *buf, size_t n) +{ + size_t m = minimum(n, rs->rs_have); + uint8_t *ks = rs->rs_buf + sizeof(rs->rs_buf) - rs->rs_have; + memcpy(buf, ks, m); + memset(ks, 0, m); + rs->rs_have -= m; + return m; +} + +static inline void +_rs_random_buf(rand_state* rs, void *_buf, size_t n) +{ + uint8_t *buf = (uint8_t *)_buf; + + _rs_stir_if_needed(rs, n); + while (n > 0) { + if (rs->rs_have > 0) { + size_t m = _rs_consume(rs, buf, n); + buf += m; + n -= m; + } else + _rs_rekey(rs, NULL, 0); + } +} + +static inline void +_rs_setup(rand_state *rs) +{ + uint8_t rnd[ARC4R_KEYSZ + ARC4R_IVSZ]; + int r = getentropy(rnd, sizeof rnd); + assert(r == 0); + + _rs_init(rs, rnd, sizeof rnd); + _rs_rekey(rs, 0, 0); +} + +#if defined(__Darwin__) || defined(__APPLE__) + +/* allocate a new rand_state and initialize it. */ +static rand_state* +_rs_new(void) +{ + rand_state *rs = (rand_state*)calloc(sizeof *rs, 1); + assert(rs); + + _rs_setup(rs); + return rs; +} + +/* + * Multi-threaded support using pthread API. Needed for OS X: + * + * https://www.reddit.com/r/cpp/comments/3bg8jc/anyone_know_if_and_when_applexcode_will_support/ + */ +static pthread_key_t Rkey; +static pthread_once_t Ronce = PTHREAD_ONCE_INIT; +static volatile uint32_t Rforked = 0; + +/* + * Fork handler to reset my context + */ +static void +atfork() +{ + // the pthread_atfork() callbacks called once per process. + // We set it to be called by the child process. + Rforked++; +} + +/* + * Run once and only once by pthread lib. We use the opportunity to + * create the thread-specific key. + */ +static void +screate() +{ + pthread_key_create(&Rkey, 0); + pthread_atfork(0, 0, atfork); +} + + +/* + * Get the per-thread rand state. Initialize if needed. + */ +static rand_state* +sget() +{ + pthread_once(&Ronce, screate); + + volatile pthread_key_t* k = &Rkey; + rand_state * z = (rand_state *)pthread_getspecific(*k); + if (!z) { + z = _rs_new(); + z->rs_pid = getpid(); + + pthread_setspecific(*k, z); + } + + /* Detect if a fork has happened */ + if (Rforked > 0 || getpid() != z->rs_pid) { + Rforked = 0; + z->rs_pid = getpid(); + _rs_setup(z); + } + + return z; +} + +#else + +/* + * Use gcc extension to declare a thread-local variable. + * + * On most systems (including x86_64), thread-local access is + * essentially free for non .so use cases. + * + */ +static __thread rand_state st = { .rs_count = 0, .rs_pid = -1, .rs_have = 0 }; +static inline rand_state* +sget() +{ + rand_state* s = &st; + + if (s->rs_count == 0 || getpid() != s->rs_pid) { + _rs_setup(s); + s->rs_pid = getpid(); + } + return s; +} + +#endif /* __Darwin__ */ + +/* + * Public API. + */ + +static inline uint32_t +__rand32(rand_state *z) +{ + uint32_t v; + _rs_random_buf(z, &v, sizeof v); + return v; +} + +uint32_t +arc4random() +{ + rand_state* z = sget(); + return __rand32(z); +} + + +void +arc4random_buf(void* b, size_t n) +{ + rand_state* z = sget(); + + _rs_random_buf(z, b, n); +} + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + rand_state* z = sget(); + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = __rand32(z); + if (r >= min) + break; + } + + return r % upper_bound; +} diff --git a/compats.c b/compats.c index f8c69a7..ff0fb2b 100644 --- a/compats.c +++ b/compats.c @@ -1,4 +1,564 @@ #include "config.h" +#if !HAVE_ARC4RANDOM +/* + * chacha-merged.c version 20080118 + * D. J. Bernstein + * Public domain. + */ + +/* $OpenBSD$ */ + +#include + +#define KEYSTREAM_ONLY + +typedef struct +{ + uint32_t input[16]; /* could be compressed */ +} chacha_ctx; + +typedef unsigned char u8; +typedef uint32_t u32; + +#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; + + (void)ivbits; + + 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 + } +} + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * Copyright (c) 2015, Sudhi Herle + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator from OpenBSD. + * + * Made fully portable and thread-safe by Sudhi Herle. + */ + +#if defined(__linux__) || defined(__wasi__) +# define _DEFAULT_SOURCE /* new glibc for getentropy() */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ARC4R_KEYSZ 32 +#define ARC4R_IVSZ 8 +#define ARC4R_BLOCKSZ 64 +#define ARC4R_RSBUFSZ (16*ARC4R_BLOCKSZ) + +// must be a power of 2 +#define REKEY_BASE (1 << 10) + +struct rand_state +{ + size_t rs_have; /* valid bytes at end of rs_buf */ + size_t rs_count; /* bytes till reseed */ + pid_t rs_pid; /* My PID */ + chacha_ctx rs_chacha; /* chacha context for random keystream */ + uint8_t rs_buf[ARC4R_RSBUFSZ]; /* keystream blocks */ +}; +typedef struct rand_state rand_state; + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +static inline void +_rs_init(rand_state* st, uint8_t *buf, size_t n) +{ + assert(n >= (ARC4R_KEYSZ + ARC4R_IVSZ)); + + chacha_keysetup(&st->rs_chacha, buf, ARC4R_KEYSZ * 8, 0); + chacha_ivsetup(&st->rs_chacha, buf + ARC4R_KEYSZ); +} + +static inline void +_rs_rekey(rand_state* st, uint8_t *dat, size_t datlen) +{ + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&st->rs_chacha, st->rs_buf, st->rs_buf, sizeof st->rs_buf); + + /* mix in optional user provided data */ + if (dat) { + size_t m = minimum(datlen, ARC4R_KEYSZ + ARC4R_IVSZ); + for (size_t i = 0; i < m; i++) + st->rs_buf[i] ^= dat[i]; + + memset(dat, 0, datlen); + } + + assert(sizeof(st->rs_buf) > (ARC4R_KEYSZ+ARC4R_IVSZ)); + + /* + * immediately reinit for backtracking resistance: + * We're consuming enough bytes to make a new chacha context (key+iv). + * Thus, we have those many fewer bytes in the entropy buf + */ + _rs_init(st, st->rs_buf, ARC4R_KEYSZ + ARC4R_IVSZ); + memset(st->rs_buf, 0, ARC4R_KEYSZ + ARC4R_IVSZ); + st->rs_have = (sizeof st->rs_buf) - ARC4R_KEYSZ - ARC4R_IVSZ; +} + +static void +_rs_stir(rand_state* st) +{ + uint8_t rnd[ARC4R_KEYSZ + ARC4R_IVSZ]; + size_t rekey_fuzz = 0; + uint8_t *fuzzp = (uint8_t*)&rekey_fuzz; + + + int r = getentropy(rnd, sizeof rnd); + assert(r == 0); + + _rs_rekey(st, rnd, sizeof(rnd)); + + /* invalidate rs_buf */ + st->rs_have = 0; + memset(st->rs_buf, 0, sizeof st->rs_buf); + + chacha_encrypt_bytes(&st->rs_chacha, fuzzp, fuzzp, sizeof rekey_fuzz); + st->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE); +} + +static inline void +_rs_stir_if_needed(rand_state* st, size_t len) +{ + if (st->rs_count <= len) + _rs_stir(st); + + st->rs_count -= len; +} + +// consume 'n' random btyes from the entropy buffer. Return total +// actually consumed. +static inline size_t +_rs_consume(rand_state *rs, uint8_t *buf, size_t n) +{ + size_t m = minimum(n, rs->rs_have); + uint8_t *ks = rs->rs_buf + sizeof(rs->rs_buf) - rs->rs_have; + memcpy(buf, ks, m); + memset(ks, 0, m); + rs->rs_have -= m; + return m; +} + +static inline void +_rs_random_buf(rand_state* rs, void *_buf, size_t n) +{ + uint8_t *buf = (uint8_t *)_buf; + + _rs_stir_if_needed(rs, n); + while (n > 0) { + if (rs->rs_have > 0) { + size_t m = _rs_consume(rs, buf, n); + buf += m; + n -= m; + } else + _rs_rekey(rs, NULL, 0); + } +} + +static inline void +_rs_setup(rand_state *rs) +{ + uint8_t rnd[ARC4R_KEYSZ + ARC4R_IVSZ]; + int r = getentropy(rnd, sizeof rnd); + assert(r == 0); + + _rs_init(rs, rnd, sizeof rnd); + _rs_rekey(rs, 0, 0); +} + +#if defined(__Darwin__) || defined(__APPLE__) + +/* allocate a new rand_state and initialize it. */ +static rand_state* +_rs_new(void) +{ + rand_state *rs = (rand_state*)calloc(sizeof *rs, 1); + assert(rs); + + _rs_setup(rs); + return rs; +} + +/* + * Multi-threaded support using pthread API. Needed for OS X: + * + * https://www.reddit.com/r/cpp/comments/3bg8jc/anyone_know_if_and_when_applexcode_will_support/ + */ +static pthread_key_t Rkey; +static pthread_once_t Ronce = PTHREAD_ONCE_INIT; +static volatile uint32_t Rforked = 0; + +/* + * Fork handler to reset my context + */ +static void +atfork() +{ + // the pthread_atfork() callbacks called once per process. + // We set it to be called by the child process. + Rforked++; +} + +/* + * Run once and only once by pthread lib. We use the opportunity to + * create the thread-specific key. + */ +static void +screate() +{ + pthread_key_create(&Rkey, 0); + pthread_atfork(0, 0, atfork); +} + + +/* + * Get the per-thread rand state. Initialize if needed. + */ +static rand_state* +sget() +{ + pthread_once(&Ronce, screate); + + volatile pthread_key_t* k = &Rkey; + rand_state * z = (rand_state *)pthread_getspecific(*k); + if (!z) { + z = _rs_new(); + z->rs_pid = getpid(); + + pthread_setspecific(*k, z); + } + + /* Detect if a fork has happened */ + if (Rforked > 0 || getpid() != z->rs_pid) { + Rforked = 0; + z->rs_pid = getpid(); + _rs_setup(z); + } + + return z; +} + +#else + +/* + * Use gcc extension to declare a thread-local variable. + * + * On most systems (including x86_64), thread-local access is + * essentially free for non .so use cases. + * + */ +static __thread rand_state st = { .rs_count = 0, .rs_pid = -1, .rs_have = 0 }; +static inline rand_state* +sget() +{ + rand_state* s = &st; + + if (s->rs_count == 0 || getpid() != s->rs_pid) { + _rs_setup(s); + s->rs_pid = getpid(); + } + return s; +} + +#endif /* __Darwin__ */ + +/* + * Public API. + */ + +static inline uint32_t +__rand32(rand_state *z) +{ + uint32_t v; + _rs_random_buf(z, &v, sizeof v); + return v; +} + +uint32_t +arc4random() +{ + rand_state* z = sget(); + return __rand32(z); +} + + +void +arc4random_buf(void* b, size_t n) +{ + rand_state* z = sget(); + + _rs_random_buf(z, b, n); +} + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + rand_state* z = sget(); + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = __rand32(z); + if (r >= min) + break; + } + + return r % upper_bound; +} +#endif /* !HAVE_ARC4RANDOM */ #if !HAVE_BLOWFISH /* $OpenBSD: blowfish.c,v 1.19 2015/09/11 09:18:27 guenther Exp $ */ /* diff --git a/configure b/configure index 570ba1f..1096c92 100755 --- a/configure +++ b/configure @@ -459,6 +459,60 @@ cat << __HEREDOC__ #ifndef OCONFIGURE_CONFIG_H #define OCONFIGURE_CONFIG_H +#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} +#define HAVE_BLOWFISH ${HAVE_BLOWFISH} +#define HAVE_B64_NTOP ${HAVE_B64_NTOP} +#define HAVE_CAPSICUM ${HAVE_CAPSICUM} +#define HAVE_CRYPT ${HAVE_CRYPT} +#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} +#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} +#define HAVE_ERR ${HAVE_ERR} +#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} +#define HAVE_FTS ${HAVE_FTS} +#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} +#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} +#define HAVE_INFTIM ${HAVE_INFTIM} +#define HAVE_LANDLOCK ${HAVE_LANDLOCK} +#define HAVE_MD5 ${HAVE_MD5} +#define HAVE_MEMMEM ${HAVE_MEMMEM} +#define HAVE_MEMRCHR ${HAVE_MEMRCHR} +#define HAVE_MEMSET_S ${HAVE_MEMSET_S} +#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} +#define HAVE_MKNODAT ${HAVE_MKNODAT} +#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} +#define HAVE_PASSWORD_LEN ${HAVE_PASSWORD_LEN} +#define HAVE_PATH_MAX ${HAVE_PATH_MAX} +#define HAVE_PLEDGE ${HAVE_PLEDGE} +#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} +#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} +#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} +#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} +#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} +#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} +#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} +#define HAVE_SETRESGID ${HAVE_SETRESGID} +#define HAVE_SETRESUID ${HAVE_SETRESUID} +#define HAVE_SHA2 ${HAVE_SHA2} +#define HAVE_SHA2_H ${HAVE_SHA2} +#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} +#define HAVE_STRLCAT ${HAVE_STRLCAT} +#define HAVE_STRLCPY ${HAVE_STRLCPY} +#define HAVE_STRNDUP ${HAVE_STRNDUP} +#define HAVE_STRNLEN ${HAVE_STRNLEN} +#define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} +#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} +#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} +#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} +#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} +#define HAVE_SYS_TREE ${HAVE_SYS_TREE} +#define HAVE_SYSTRACE ${HAVE_SYSTRACE} +#define HAVE_UNVEIL ${HAVE_UNVEIL} +#define HAVE_TERMIOS ${HAVE_TERMIOS} +#define HAVE_TIMINGSAFE_BCMP ${HAVE_TIMINGSAFE_BCMP} +#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} +#define HAVE___PROGNAME ${HAVE___PROGNAME} + #ifdef __cplusplus # error "Do not use C++: this is a C application." #endif @@ -487,7 +541,6 @@ cat << __HEREDOC__ #if !defined(__END_DECLS) # define __END_DECLS #endif - __HEREDOC__ # This is just for size_t, mode_t, and dev_t. @@ -514,120 +567,47 @@ if [ ${HAVE_BLOWFISH} -eq 0 -o \ ${HAVE_STRNLEN} -eq 0 ] then echo "#include /* size_t, mode_t, dev_t */ " - echo fi -if [ ${HAVE_MD5} -eq 0 -o \ +if [ ${HAVE_ARC4RANDOM} -eq 0 -o \ + ${HAVE_MD5} -eq 0 -o \ ${HAVE_SHA2} -eq 0 ] then echo "#include /* C99 [u]int[nn]_t types */" - echo fi if [ ${HAVE_ERR} -eq 0 ] then echo "#include /* err(3) */" - echo fi -# Now we handle our HAVE_xxxx values. -# Most will just be defined as 0 or 1. - if [ ${HAVE_PATH_MAX} -eq 0 ] then echo "#define PATH_MAX 4096" - echo fi if [ ${HAVE_WAIT_ANY} -eq 0 ] then echo "#define WAIT_ANY (-1) /* sys/wait.h */" echo "#define WAIT_MYPGRP 0" - echo fi if [ ${HAVE_PASSWORD_LEN} -eq 0 ] then echo "#define _PASSWORD_LEN (128) /* pwd.h */" - echo fi if [ ${HAVE_INFTIM} -eq 0 ] then echo "#define INFTIM (-1) /* poll.h */" - echo fi -cat << __HEREDOC__ -/* - * Results of configuration feature-testing. - */ -#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} -#define HAVE_BLOWFISH ${HAVE_BLOWFISH} -#define HAVE_B64_NTOP ${HAVE_B64_NTOP} -#define HAVE_CAPSICUM ${HAVE_CAPSICUM} -#define HAVE_CRYPT ${HAVE_CRYPT} -#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} -#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} -#define HAVE_ERR ${HAVE_ERR} -#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} -#define HAVE_FTS ${HAVE_FTS} -#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} -#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} -#define HAVE_INFTIM ${HAVE_INFTIM} -#define HAVE_LANDLOCK ${HAVE_LANDLOCK} -#define HAVE_MD5 ${HAVE_MD5} -#define HAVE_MEMMEM ${HAVE_MEMMEM} -#define HAVE_MEMRCHR ${HAVE_MEMRCHR} -#define HAVE_MEMSET_S ${HAVE_MEMSET_S} -#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} -#define HAVE_MKNODAT ${HAVE_MKNODAT} -#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} -#define HAVE_PASSWORD_LEN ${HAVE_PASSWORD_LEN} -#define HAVE_PATH_MAX ${HAVE_PATH_MAX} -#define HAVE_PLEDGE ${HAVE_PLEDGE} -#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} -#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} -#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} -#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} -#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} -#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} -#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} -#define HAVE_SETRESGID ${HAVE_SETRESGID} -#define HAVE_SETRESUID ${HAVE_SETRESUID} -#define HAVE_SHA2 ${HAVE_SHA2} -#define HAVE_SHA2_H ${HAVE_SHA2} -#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} -#define HAVE_STRLCAT ${HAVE_STRLCAT} -#define HAVE_STRLCPY ${HAVE_STRLCPY} -#define HAVE_STRNDUP ${HAVE_STRNDUP} -#define HAVE_STRNLEN ${HAVE_STRNLEN} -#define HAVE_STRTONUM ${HAVE_STRTONUM} -#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} -#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} -#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} -#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} -#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} -#define HAVE_SYS_TREE ${HAVE_SYS_TREE} -#define HAVE_SYSTRACE ${HAVE_SYSTRACE} -#define HAVE_UNVEIL ${HAVE_UNVEIL} -#define HAVE_TERMIOS ${HAVE_TERMIOS} -#define HAVE_TIMINGSAFE_BCMP ${HAVE_TIMINGSAFE_BCMP} -#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} -#define HAVE___PROGNAME ${HAVE___PROGNAME} - -__HEREDOC__ - -# Compat for libkern/OSByteOrder.h in place of endian.h. - -[ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ - ${HAVE_ENDIAN_H} -eq 0 -a \ - ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ - ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ - && cat << __HEREDOC__ -/* - * endian.h compatibility with libkern/OSByteOrder.h. - */ +if [ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] +then + cat << __HEREDOC__ #define htobe16(x) OSSwapHostToBigInt16(x) #define htole16(x) OSSwapHostToLittleInt16(x) #define be16toh(x) OSSwapBigToHostInt16(x) @@ -640,17 +620,15 @@ __HEREDOC__ #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) - __HEREDOC__ +fi -[ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ - ${HAVE_ENDIAN_H} -eq 0 -a \ - ${HAVE_OSBYTEORDER_H} -eq 0 -a \ - ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ - && cat << __HEREDOC__ -/* - * endian.h compatibility with sys/byteorder.h. - */ +if [ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_OSBYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] +then + cat << __HEREDOC__ #define htobe16(x) BE_16(x) #define htole16(x) LE_16(x) #define be16toh(x) BE_16(x) @@ -663,10 +641,8 @@ __HEREDOC__ #define htole64(x) LE_64(x) #define be64toh(x) BE_64(x) #define le64toh(x) LE_64(x) - __HEREDOC__ - -# Make minor()/major()/makedev() easier to use. +fi cat << __HEREDOC__ /* @@ -681,12 +657,6 @@ cat << __HEREDOC__ #else # define COMPAT_MAJOR_MINOR_H #endif - -__HEREDOC__ - -# Make endian.h easier by providing a COMPAT_ENDIAN_H. - -cat << __HEREDOC__ /* * Make it easier to include endian.h forms. */ @@ -703,16 +673,13 @@ cat << __HEREDOC__ # warning Please e-mail the maintainers with your OS. # define COMPAT_ENDIAN_H #endif - __HEREDOC__ # Now we do our function declarations for missing functions. -[ ${HAVE_ERR} -eq 0 ] && \ +if [ ${HAVE_ERR} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility functions for err(3). - */ extern void err(int, const char *, ...) __attribute__((noreturn)); extern void errc(int, int, const char *, ...) __attribute__((noreturn)); extern void errx(int, const char *, ...) __attribute__((noreturn)); @@ -725,40 +692,32 @@ extern void warnc(int, const char *, ...); extern void vwarn(const char *, va_list); extern void vwarnc(int, const char *, va_list); extern void vwarnx(const char *, va_list); - __HEREDOC__ +fi -[ ${HAVE_MD5} -eq 0 ] && \ +if [ ${HAVE_MD5} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for md4(3). - */ #define MD5_BLOCK_LENGTH 64 #define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) - typedef struct MD5Context { uint32_t state[4]; uint64_t count; uint8_t buffer[MD5_BLOCK_LENGTH]; } MD5_CTX; - extern void MD5Init(MD5_CTX *); extern void MD5Update(MD5_CTX *, const uint8_t *, size_t); extern void MD5Pad(MD5_CTX *); extern void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]); extern char *MD5End(MD5_CTX *, char *); extern void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *); - __HEREDOC__ +fi -[ ${HAVE_SHA2} -eq 0 ] && \ +if [ ${HAVE_SHA2} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for sha2(3). - */ - -/*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) @@ -771,8 +730,6 @@ __HEREDOC__ #define SHA512_256_BLOCK_LENGTH 128 #define SHA512_256_DIGEST_LENGTH 32 #define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1) - -/*** SHA-224/256/384/512 Context Structure *******************************/ typedef struct _SHA2_CTX { union { uint32_t st32[8]; @@ -781,7 +738,6 @@ typedef struct _SHA2_CTX { uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA2_CTX; - void SHA256Init(SHA2_CTX *); void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]); void SHA256Update(SHA2_CTX *, const uint8_t *, size_t); @@ -791,7 +747,6 @@ char *SHA256End(SHA2_CTX *, char *); char *SHA256File(const char *, char *); char *SHA256FileChunk(const char *, char *, off_t, off_t); char *SHA256Data(const uint8_t *, size_t, char *); - void SHA384Init(SHA2_CTX *); void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]); void SHA384Update(SHA2_CTX *, const uint8_t *, size_t); @@ -801,7 +756,6 @@ char *SHA384End(SHA2_CTX *, char *); char *SHA384File(const char *, char *); char *SHA384FileChunk(const char *, char *, off_t, off_t); char *SHA384Data(const uint8_t *, size_t, char *); - void SHA512Init(SHA2_CTX *); void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]); void SHA512Update(SHA2_CTX *, const uint8_t *, size_t); @@ -811,10 +765,11 @@ char *SHA512End(SHA2_CTX *, char *); char *SHA512File(const char *, char *); char *SHA512FileChunk(const char *, char *, off_t, off_t); char *SHA512Data(const uint8_t *, size_t, char *); - __HEREDOC__ +fi -if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then +if [ ${HAVE_SECCOMP_FILTER} -eq 1 ] +then seccomp_audit_arch= arch=$(uname -m 2>/dev/null || echo unknown) case "$arch" in @@ -859,12 +814,8 @@ if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then then echo "seccomp-arch: $seccomp_audit_arch" 1>&2 cat << __HEREDOC__ -/* - * Seccomp is both available and has a recognised architecture. - */ #define HAVE_SECCOMP_FILTER 1 #define SECCOMP_AUDIT_ARCH $seccomp_audit_arch - __HEREDOC__ else echo "seccomp-arch: disabling (unknown: `uname -m`)" 1>&2 @@ -875,74 +826,62 @@ __HEREDOC__ * maintainers. */ #define HAVE_SECCOMP_FILTER 0 - __HEREDOC__ fi else cat << __HEREDOC__ #define HAVE_SECCOMP_FILTER 0 - __HEREDOC__ fi -[ ${HAVE_B64_NTOP} -eq 0 ] && \ +if [ ${HAVE_B64_NTOP} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for b64_ntop(3). - */ extern int b64_ntop(unsigned char const *, size_t, char *, size_t); extern int b64_pton(char const *, unsigned char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_SCAN_SCALED} -eq 0 ] && \ +if [ ${HAVE_SCAN_SCALED} -eq 0 ] +then cat << __HEREDOC__ #define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */ -int fmt_scaled(long long, char *); -int scan_scaled(char *, long long *); +int fmt_scaled(long long, char *); +int scan_scaled(char *, long long *); __HEREDOC__ +fi -[ ${HAVE_EXPLICIT_BZERO} -eq 0 ] && \ +if [ ${HAVE_EXPLICIT_BZERO} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for explicit_bzero(3). - */ extern void explicit_bzero(void *, size_t); - __HEREDOC__ +fi -[ ${HAVE_MEMMEM} -eq 0 ] && \ +if [ ${HAVE_MEMMEM} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for memmem(3). - */ void *memmem(const void *, size_t, const void *, size_t); - __HEREDOC__ +fi -[ ${HAVE_MEMRCHR} -eq 0 ] && \ +if [ ${HAVE_MEMRCHR} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for memrchr(3). - */ void *memrchr(const void *b, int, size_t); - __HEREDOC__ +fi -[ ${HAVE_GETPROGNAME} -eq 0 ] && \ +if [ ${HAVE_GETPROGNAME} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for getprogname(3). - */ extern const char *getprogname(void); - __HEREDOC__ +fi -[ ${HAVE_READPASSPHRASE} -eq 0 ] && \ +if [ ${HAVE_READPASSPHRASE} -eq 0 ] +then cat << __HEREDOC__ -/* - * Macros and function required for readpassphrase(3). - */ #define RPP_ECHO_OFF 0x00 #define RPP_ECHO_ON 0x01 #define RPP_REQUIRE_TTY 0x02 @@ -951,113 +890,89 @@ __HEREDOC__ #define RPP_SEVENBIT 0x10 #define RPP_STDIN 0x20 char *readpassphrase(const char *, char *, size_t, int); - __HEREDOC__ +fi -[ ${HAVE_REALLOCARRAY} -eq 0 ] && \ +if [ ${HAVE_REALLOCARRAY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for reallocarray(3). - */ extern void *reallocarray(void *, size_t, size_t); - __HEREDOC__ +fi -[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \ +if [ ${HAVE_RECALLOCARRAY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for recallocarray(3). - */ extern void *recallocarray(void *, size_t, size_t, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRLCAT} -eq 0 ] && \ +if [ ${HAVE_STRLCAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strlcat(3). - */ extern size_t strlcat(char *, const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRLCPY} -eq 0 ] && \ +if [ ${HAVE_STRLCPY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strlcpy(3). - */ extern size_t strlcpy(char *, const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRNDUP} -eq 0 ] && \ +if [ ${HAVE_STRNDUP} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strndup(3). - */ extern char *strndup(const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRNLEN} -eq 0 ] && \ +if [ ${HAVE_STRNLEN} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strnlen(3). - */ extern size_t strnlen(const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRTONUM} -eq 0 ] && \ +if [ ${HAVE_STRTONUM} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strotnum(3). - */ extern long long strtonum(const char *, long long, long long, const char **); - __HEREDOC__ +fi -[ ${HAVE_MKFIFOAT} -eq 0 ] && \ +if [ ${HAVE_MKFIFOAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for mkfifoat(2). - */ int mkfifoat(int, const char *, mode_t); - __HEREDOC__ +fi -[ ${HAVE_MKNODAT} -eq 0 ] && \ +if [ ${HAVE_MKNODAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for mknodat(2). - */ int mknodat(int, const char *, mode_t, dev_t); - __HEREDOC__ +fi -[ ${HAVE_SETRESGID} -eq 0 ] && \ +if [ ${HAVE_SETRESGID} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for setresgid(2). - */ int setresgid(gid_t rgid, gid_t egid, gid_t sgid); - __HEREDOC__ +fi -[ ${HAVE_SETRESUID} -eq 0 ] && \ +if [ ${HAVE_SETRESUID} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for setresuid(2). - */ int setresuid(uid_t ruid, uid_t euid, uid_t suid); - __HEREDOC__ +fi -if [ ${HAVE_SYS_QUEUE} -eq 0 ]; then +if [ ${HAVE_SYS_QUEUE} -eq 0 ] +then cat << __HEREDOC__ -/* - * A compatible version of OpenBSD . - */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -1674,15 +1589,12 @@ struct { \\ TAILQ_INIT((head2)); \\ } \\ } while (0) - __HEREDOC__ fi -if [ ${HAVE_SYS_TREE} -eq 0 ]; then +if [ ${HAVE_SYS_TREE} -eq 0 ] +then cat << __HEREDOC__ -/* - * A compatible version of OpenBSD . - */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -2427,15 +2339,12 @@ name##_RB_MINMAX(struct name *head, int val) \\ for ((x) = RB_MAX(name, head); \\ ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \\ (x) = (y)) - __HEREDOC__ fi -if [ ${HAVE_FTS} -eq 0 ]; then +if [ ${HAVE_FTS} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for fts(3) functions. - */ typedef struct { struct _ftsent *fts_cur; /* current node */ struct _ftsent *fts_child; /* linked list of children */ @@ -2458,7 +2367,6 @@ typedef struct { #define FTS_STOP 0x2000 /* (private) unrecoverable error */ int fts_options; /* fts_open options, global flags */ } FTS; - typedef struct _ftsent { struct _ftsent *fts_cycle; /* cycle node */ struct _ftsent *fts_parent; /* parent directory */ @@ -2504,36 +2412,33 @@ typedef struct _ftsent { struct stat *fts_statp; /* stat(2) information */ char fts_name[1]; /* file name */ } FTSENT; - FTSENT *fts_children(FTS *, int); int fts_close(FTS *); FTS *fts_open(char * const *, int, int (*)(const FTSENT **, const FTSENT **)); FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); - __HEREDOC__ fi -if [ ${HAVE_CRYPT_NEWHASH} -eq 0 ]; then +if [ ${HAVE_CRYPT_NEWHASH} -eq 0 ] +then cat << __HEREDOC__ int crypt_newhash(const char *, const char *, char *, size_t); int crypt_checkpass(const char *, const char *); - __HEREDOC__ fi -if [ ${HAVE_BLOWFISH} -eq 0 ]; then +if [ ${HAVE_BLOWFISH} -eq 0 ] +then cat << __HEREDOC__ #define BLF_N 16 #define BLF_MAXKEYLEN ((BLF_N-2)*4) #define BLF_MAXUTILIZED ((BLF_N+2)*4) - typedef struct BlowfishContext { u_int32_t S[4][256]; u_int32_t P[BLF_N + 2]; } blf_ctx; - void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_initstate(blf_ctx *); @@ -2548,15 +2453,23 @@ void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); - __HEREDOC__ fi -if [ ${HAVE_TIMINGSAFE_BCMP} -eq 0 ]; then +if [ ${HAVE_TIMINGSAFE_BCMP} -eq 0 ] +then cat << __HEREDOC__ int timingsafe_bcmp(const void *, const void *, size_t); int timingsafe_memcmp(const void *, const void *, size_t); +__HEREDOC__ +fi +if [ ${HAVE_ARC4RANDOM} -eq 0 ] +then + cat << __HEREDOC__ +uint32_t arc4random(void); +uint32_t arc4random_uniform(uint32_t); +void arc4random_buf(void *buf, size_t); __HEREDOC__ fi diff --git a/configure.in b/configure.in index 41106bc..ebb1cb7 100644 --- a/configure.in +++ b/configure.in @@ -459,6 +459,60 @@ cat << __HEREDOC__ #ifndef OCONFIGURE_CONFIG_H #define OCONFIGURE_CONFIG_H +#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} +#define HAVE_BLOWFISH ${HAVE_BLOWFISH} +#define HAVE_B64_NTOP ${HAVE_B64_NTOP} +#define HAVE_CAPSICUM ${HAVE_CAPSICUM} +#define HAVE_CRYPT ${HAVE_CRYPT} +#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} +#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} +#define HAVE_ERR ${HAVE_ERR} +#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} +#define HAVE_FTS ${HAVE_FTS} +#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} +#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} +#define HAVE_INFTIM ${HAVE_INFTIM} +#define HAVE_LANDLOCK ${HAVE_LANDLOCK} +#define HAVE_MD5 ${HAVE_MD5} +#define HAVE_MEMMEM ${HAVE_MEMMEM} +#define HAVE_MEMRCHR ${HAVE_MEMRCHR} +#define HAVE_MEMSET_S ${HAVE_MEMSET_S} +#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} +#define HAVE_MKNODAT ${HAVE_MKNODAT} +#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} +#define HAVE_PASSWORD_LEN ${HAVE_PASSWORD_LEN} +#define HAVE_PATH_MAX ${HAVE_PATH_MAX} +#define HAVE_PLEDGE ${HAVE_PLEDGE} +#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} +#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} +#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} +#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} +#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} +#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} +#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} +#define HAVE_SETRESGID ${HAVE_SETRESGID} +#define HAVE_SETRESUID ${HAVE_SETRESUID} +#define HAVE_SHA2 ${HAVE_SHA2} +#define HAVE_SHA2_H ${HAVE_SHA2} +#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} +#define HAVE_STRLCAT ${HAVE_STRLCAT} +#define HAVE_STRLCPY ${HAVE_STRLCPY} +#define HAVE_STRNDUP ${HAVE_STRNDUP} +#define HAVE_STRNLEN ${HAVE_STRNLEN} +#define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} +#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} +#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} +#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} +#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} +#define HAVE_SYS_TREE ${HAVE_SYS_TREE} +#define HAVE_SYSTRACE ${HAVE_SYSTRACE} +#define HAVE_UNVEIL ${HAVE_UNVEIL} +#define HAVE_TERMIOS ${HAVE_TERMIOS} +#define HAVE_TIMINGSAFE_BCMP ${HAVE_TIMINGSAFE_BCMP} +#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} +#define HAVE___PROGNAME ${HAVE___PROGNAME} + #ifdef __cplusplus # error "Do not use C++: this is a C application." #endif @@ -487,7 +541,6 @@ cat << __HEREDOC__ #if !defined(__END_DECLS) # define __END_DECLS #endif - __HEREDOC__ # This is just for size_t, mode_t, and dev_t. @@ -514,120 +567,47 @@ if [ ${HAVE_BLOWFISH} -eq 0 -o \ ${HAVE_STRNLEN} -eq 0 ] then echo "#include /* size_t, mode_t, dev_t */ " - echo fi -if [ ${HAVE_MD5} -eq 0 -o \ +if [ ${HAVE_ARC4RANDOM} -eq 0 -o \ + ${HAVE_MD5} -eq 0 -o \ ${HAVE_SHA2} -eq 0 ] then echo "#include /* C99 [u]int[nn]_t types */" - echo fi if [ ${HAVE_ERR} -eq 0 ] then echo "#include /* err(3) */" - echo fi -# Now we handle our HAVE_xxxx values. -# Most will just be defined as 0 or 1. - if [ ${HAVE_PATH_MAX} -eq 0 ] then echo "#define PATH_MAX 4096" - echo fi if [ ${HAVE_WAIT_ANY} -eq 0 ] then echo "#define WAIT_ANY (-1) /* sys/wait.h */" echo "#define WAIT_MYPGRP 0" - echo fi if [ ${HAVE_PASSWORD_LEN} -eq 0 ] then echo "#define _PASSWORD_LEN (128) /* pwd.h */" - echo fi if [ ${HAVE_INFTIM} -eq 0 ] then echo "#define INFTIM (-1) /* poll.h */" - echo fi -cat << __HEREDOC__ -/* - * Results of configuration feature-testing. - */ -#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} -#define HAVE_BLOWFISH ${HAVE_BLOWFISH} -#define HAVE_B64_NTOP ${HAVE_B64_NTOP} -#define HAVE_CAPSICUM ${HAVE_CAPSICUM} -#define HAVE_CRYPT ${HAVE_CRYPT} -#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} -#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} -#define HAVE_ERR ${HAVE_ERR} -#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} -#define HAVE_FTS ${HAVE_FTS} -#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} -#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} -#define HAVE_INFTIM ${HAVE_INFTIM} -#define HAVE_LANDLOCK ${HAVE_LANDLOCK} -#define HAVE_MD5 ${HAVE_MD5} -#define HAVE_MEMMEM ${HAVE_MEMMEM} -#define HAVE_MEMRCHR ${HAVE_MEMRCHR} -#define HAVE_MEMSET_S ${HAVE_MEMSET_S} -#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} -#define HAVE_MKNODAT ${HAVE_MKNODAT} -#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} -#define HAVE_PASSWORD_LEN ${HAVE_PASSWORD_LEN} -#define HAVE_PATH_MAX ${HAVE_PATH_MAX} -#define HAVE_PLEDGE ${HAVE_PLEDGE} -#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} -#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} -#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} -#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} -#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} -#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} -#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} -#define HAVE_SETRESGID ${HAVE_SETRESGID} -#define HAVE_SETRESUID ${HAVE_SETRESUID} -#define HAVE_SHA2 ${HAVE_SHA2} -#define HAVE_SHA2_H ${HAVE_SHA2} -#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} -#define HAVE_STRLCAT ${HAVE_STRLCAT} -#define HAVE_STRLCPY ${HAVE_STRLCPY} -#define HAVE_STRNDUP ${HAVE_STRNDUP} -#define HAVE_STRNLEN ${HAVE_STRNLEN} -#define HAVE_STRTONUM ${HAVE_STRTONUM} -#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} -#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} -#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} -#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} -#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} -#define HAVE_SYS_TREE ${HAVE_SYS_TREE} -#define HAVE_SYSTRACE ${HAVE_SYSTRACE} -#define HAVE_UNVEIL ${HAVE_UNVEIL} -#define HAVE_TERMIOS ${HAVE_TERMIOS} -#define HAVE_TIMINGSAFE_BCMP ${HAVE_TIMINGSAFE_BCMP} -#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} -#define HAVE___PROGNAME ${HAVE___PROGNAME} - -__HEREDOC__ - -# Compat for libkern/OSByteOrder.h in place of endian.h. - -[ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ - ${HAVE_ENDIAN_H} -eq 0 -a \ - ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ - ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ - && cat << __HEREDOC__ -/* - * endian.h compatibility with libkern/OSByteOrder.h. - */ +if [ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] +then + cat << __HEREDOC__ #define htobe16(x) OSSwapHostToBigInt16(x) #define htole16(x) OSSwapHostToLittleInt16(x) #define be16toh(x) OSSwapBigToHostInt16(x) @@ -640,17 +620,15 @@ __HEREDOC__ #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) - __HEREDOC__ +fi -[ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ - ${HAVE_ENDIAN_H} -eq 0 -a \ - ${HAVE_OSBYTEORDER_H} -eq 0 -a \ - ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ - && cat << __HEREDOC__ -/* - * endian.h compatibility with sys/byteorder.h. - */ +if [ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_OSBYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] +then + cat << __HEREDOC__ #define htobe16(x) BE_16(x) #define htole16(x) LE_16(x) #define be16toh(x) BE_16(x) @@ -663,10 +641,8 @@ __HEREDOC__ #define htole64(x) LE_64(x) #define be64toh(x) BE_64(x) #define le64toh(x) LE_64(x) - __HEREDOC__ - -# Make minor()/major()/makedev() easier to use. +fi cat << __HEREDOC__ /* @@ -681,12 +657,6 @@ cat << __HEREDOC__ #else # define COMPAT_MAJOR_MINOR_H #endif - -__HEREDOC__ - -# Make endian.h easier by providing a COMPAT_ENDIAN_H. - -cat << __HEREDOC__ /* * Make it easier to include endian.h forms. */ @@ -703,16 +673,13 @@ cat << __HEREDOC__ # warning Please e-mail the maintainers with your OS. # define COMPAT_ENDIAN_H #endif - __HEREDOC__ # Now we do our function declarations for missing functions. -[ ${HAVE_ERR} -eq 0 ] && \ +if [ ${HAVE_ERR} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility functions for err(3). - */ extern void err(int, const char *, ...) __attribute__((noreturn)); extern void errc(int, int, const char *, ...) __attribute__((noreturn)); extern void errx(int, const char *, ...) __attribute__((noreturn)); @@ -725,40 +692,32 @@ extern void warnc(int, const char *, ...); extern void vwarn(const char *, va_list); extern void vwarnc(int, const char *, va_list); extern void vwarnx(const char *, va_list); - __HEREDOC__ +fi -[ ${HAVE_MD5} -eq 0 ] && \ +if [ ${HAVE_MD5} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for md4(3). - */ #define MD5_BLOCK_LENGTH 64 #define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) - typedef struct MD5Context { uint32_t state[4]; uint64_t count; uint8_t buffer[MD5_BLOCK_LENGTH]; } MD5_CTX; - extern void MD5Init(MD5_CTX *); extern void MD5Update(MD5_CTX *, const uint8_t *, size_t); extern void MD5Pad(MD5_CTX *); extern void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]); extern char *MD5End(MD5_CTX *, char *); extern void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *); - __HEREDOC__ +fi -[ ${HAVE_SHA2} -eq 0 ] && \ +if [ ${HAVE_SHA2} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for sha2(3). - */ - -/*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) @@ -771,8 +730,6 @@ __HEREDOC__ #define SHA512_256_BLOCK_LENGTH 128 #define SHA512_256_DIGEST_LENGTH 32 #define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1) - -/*** SHA-224/256/384/512 Context Structure *******************************/ typedef struct _SHA2_CTX { union { uint32_t st32[8]; @@ -781,7 +738,6 @@ typedef struct _SHA2_CTX { uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA2_CTX; - void SHA256Init(SHA2_CTX *); void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]); void SHA256Update(SHA2_CTX *, const uint8_t *, size_t); @@ -791,7 +747,6 @@ char *SHA256End(SHA2_CTX *, char *); char *SHA256File(const char *, char *); char *SHA256FileChunk(const char *, char *, off_t, off_t); char *SHA256Data(const uint8_t *, size_t, char *); - void SHA384Init(SHA2_CTX *); void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]); void SHA384Update(SHA2_CTX *, const uint8_t *, size_t); @@ -801,7 +756,6 @@ char *SHA384End(SHA2_CTX *, char *); char *SHA384File(const char *, char *); char *SHA384FileChunk(const char *, char *, off_t, off_t); char *SHA384Data(const uint8_t *, size_t, char *); - void SHA512Init(SHA2_CTX *); void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]); void SHA512Update(SHA2_CTX *, const uint8_t *, size_t); @@ -811,10 +765,11 @@ char *SHA512End(SHA2_CTX *, char *); char *SHA512File(const char *, char *); char *SHA512FileChunk(const char *, char *, off_t, off_t); char *SHA512Data(const uint8_t *, size_t, char *); - __HEREDOC__ +fi -if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then +if [ ${HAVE_SECCOMP_FILTER} -eq 1 ] +then seccomp_audit_arch= arch=$(uname -m 2>/dev/null || echo unknown) case "$arch" in @@ -859,12 +814,8 @@ if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then then echo "seccomp-arch: $seccomp_audit_arch" 1>&2 cat << __HEREDOC__ -/* - * Seccomp is both available and has a recognised architecture. - */ #define HAVE_SECCOMP_FILTER 1 #define SECCOMP_AUDIT_ARCH $seccomp_audit_arch - __HEREDOC__ else echo "seccomp-arch: disabling (unknown: `uname -m`)" 1>&2 @@ -875,74 +826,62 @@ __HEREDOC__ * maintainers. */ #define HAVE_SECCOMP_FILTER 0 - __HEREDOC__ fi else cat << __HEREDOC__ #define HAVE_SECCOMP_FILTER 0 - __HEREDOC__ fi -[ ${HAVE_B64_NTOP} -eq 0 ] && \ +if [ ${HAVE_B64_NTOP} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for b64_ntop(3). - */ extern int b64_ntop(unsigned char const *, size_t, char *, size_t); extern int b64_pton(char const *, unsigned char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_SCAN_SCALED} -eq 0 ] && \ +if [ ${HAVE_SCAN_SCALED} -eq 0 ] +then cat << __HEREDOC__ #define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */ -int fmt_scaled(long long, char *); -int scan_scaled(char *, long long *); +int fmt_scaled(long long, char *); +int scan_scaled(char *, long long *); __HEREDOC__ +fi -[ ${HAVE_EXPLICIT_BZERO} -eq 0 ] && \ +if [ ${HAVE_EXPLICIT_BZERO} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for explicit_bzero(3). - */ extern void explicit_bzero(void *, size_t); - __HEREDOC__ +fi -[ ${HAVE_MEMMEM} -eq 0 ] && \ +if [ ${HAVE_MEMMEM} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for memmem(3). - */ void *memmem(const void *, size_t, const void *, size_t); - __HEREDOC__ +fi -[ ${HAVE_MEMRCHR} -eq 0 ] && \ +if [ ${HAVE_MEMRCHR} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for memrchr(3). - */ void *memrchr(const void *b, int, size_t); - __HEREDOC__ +fi -[ ${HAVE_GETPROGNAME} -eq 0 ] && \ +if [ ${HAVE_GETPROGNAME} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for getprogname(3). - */ extern const char *getprogname(void); - __HEREDOC__ +fi -[ ${HAVE_READPASSPHRASE} -eq 0 ] && \ +if [ ${HAVE_READPASSPHRASE} -eq 0 ] +then cat << __HEREDOC__ -/* - * Macros and function required for readpassphrase(3). - */ #define RPP_ECHO_OFF 0x00 #define RPP_ECHO_ON 0x01 #define RPP_REQUIRE_TTY 0x02 @@ -951,133 +890,103 @@ __HEREDOC__ #define RPP_SEVENBIT 0x10 #define RPP_STDIN 0x20 char *readpassphrase(const char *, char *, size_t, int); - __HEREDOC__ +fi -[ ${HAVE_REALLOCARRAY} -eq 0 ] && \ +if [ ${HAVE_REALLOCARRAY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for reallocarray(3). - */ extern void *reallocarray(void *, size_t, size_t); - __HEREDOC__ +fi -[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \ +if [ ${HAVE_RECALLOCARRAY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for recallocarray(3). - */ extern void *recallocarray(void *, size_t, size_t, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRLCAT} -eq 0 ] && \ +if [ ${HAVE_STRLCAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strlcat(3). - */ extern size_t strlcat(char *, const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRLCPY} -eq 0 ] && \ +if [ ${HAVE_STRLCPY} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strlcpy(3). - */ extern size_t strlcpy(char *, const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRNDUP} -eq 0 ] && \ +if [ ${HAVE_STRNDUP} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strndup(3). - */ extern char *strndup(const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRNLEN} -eq 0 ] && \ +if [ ${HAVE_STRNLEN} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strnlen(3). - */ extern size_t strnlen(const char *, size_t); - __HEREDOC__ +fi -[ ${HAVE_STRTONUM} -eq 0 ] && \ +if [ ${HAVE_STRTONUM} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for strotnum(3). - */ extern long long strtonum(const char *, long long, long long, const char **); - __HEREDOC__ +fi -[ ${HAVE_MKFIFOAT} -eq 0 ] && \ +if [ ${HAVE_MKFIFOAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for mkfifoat(2). - */ int mkfifoat(int, const char *, mode_t); - __HEREDOC__ +fi -[ ${HAVE_MKNODAT} -eq 0 ] && \ +if [ ${HAVE_MKNODAT} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for mknodat(2). - */ int mknodat(int, const char *, mode_t, dev_t); - __HEREDOC__ +fi -[ ${HAVE_SETRESGID} -eq 0 ] && \ +if [ ${HAVE_SETRESGID} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for setresgid(2). - */ int setresgid(gid_t rgid, gid_t egid, gid_t sgid); - __HEREDOC__ +fi -[ ${HAVE_SETRESUID} -eq 0 ] && \ +if [ ${HAVE_SETRESUID} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for setresuid(2). - */ int setresuid(uid_t ruid, uid_t euid, uid_t suid); - __HEREDOC__ +fi -if [ ${HAVE_SYS_QUEUE} -eq 0 ]; then +if [ ${HAVE_SYS_QUEUE} -eq 0 ] +then cat << __HEREDOC__ -/* - * A compatible version of OpenBSD . - */ @CONFIGURE_SYS_QUEUE_H@ - __HEREDOC__ fi -if [ ${HAVE_SYS_TREE} -eq 0 ]; then +if [ ${HAVE_SYS_TREE} -eq 0 ] +then cat << __HEREDOC__ -/* - * A compatible version of OpenBSD . - */ @CONFIGURE_SYS_TREE_H@ - __HEREDOC__ fi -if [ ${HAVE_FTS} -eq 0 ]; then +if [ ${HAVE_FTS} -eq 0 ] +then cat << __HEREDOC__ -/* - * Compatibility for fts(3) functions. - */ typedef struct { struct _ftsent *fts_cur; /* current node */ struct _ftsent *fts_child; /* linked list of children */ @@ -1100,7 +1009,6 @@ typedef struct { #define FTS_STOP 0x2000 /* (private) unrecoverable error */ int fts_options; /* fts_open options, global flags */ } FTS; - typedef struct _ftsent { struct _ftsent *fts_cycle; /* cycle node */ struct _ftsent *fts_parent; /* parent directory */ @@ -1146,36 +1054,33 @@ typedef struct _ftsent { struct stat *fts_statp; /* stat(2) information */ char fts_name[1]; /* file name */ } FTSENT; - FTSENT *fts_children(FTS *, int); int fts_close(FTS *); FTS *fts_open(char * const *, int, int (*)(const FTSENT **, const FTSENT **)); FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); - __HEREDOC__ fi -if [ ${HAVE_CRYPT_NEWHASH} -eq 0 ]; then +if [ ${HAVE_CRYPT_NEWHASH} -eq 0 ] +then cat << __HEREDOC__ int crypt_newhash(const char *, const char *, char *, size_t); int crypt_checkpass(const char *, const char *); - __HEREDOC__ fi -if [ ${HAVE_BLOWFISH} -eq 0 ]; then +if [ ${HAVE_BLOWFISH} -eq 0 ] +then cat << __HEREDOC__ #define BLF_N 16 #define BLF_MAXKEYLEN ((BLF_N-2)*4) #define BLF_MAXUTILIZED ((BLF_N+2)*4) - typedef struct BlowfishContext { u_int32_t S[4][256]; u_int32_t P[BLF_N + 2]; } blf_ctx; - void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); void Blowfish_initstate(blf_ctx *); @@ -1190,15 +1095,23 @@ void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); - __HEREDOC__ fi -if [ ${HAVE_TIMINGSAFE_BCMP} -eq 0 ]; then +if [ ${HAVE_TIMINGSAFE_BCMP} -eq 0 ] +then cat << __HEREDOC__ int timingsafe_bcmp(const void *, const void *, size_t); int timingsafe_memcmp(const void *, const void *, size_t); +__HEREDOC__ +fi +if [ ${HAVE_ARC4RANDOM} -eq 0 ] +then + cat << __HEREDOC__ +uint32_t arc4random(void); +uint32_t arc4random_uniform(uint32_t); +void arc4random_buf(void *buf, size_t); __HEREDOC__ fi diff --git a/regress/arc4random.c b/regress/arc4random.c new file mode 100644 index 0000000..79fb964 --- /dev/null +++ b/regress/arc4random.c @@ -0,0 +1,9 @@ +#include "../config.h" + +#include + +int +main(void) +{ + return (arc4random() + 1) ? 0 : 1; +}