aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2024-06-03 16:17:02 +0000
committerEd Maste <emaste@FreeBSD.org>2024-06-03 16:19:54 +0000
commit1b2aa3deeb0dbbace9fed635fa01b6f6e8480901 (patch)
treed4f991a92b1c7c84e264b900f50f2fa0202c872a /compat
parent96dba636abec6d5451820add99300bda2ca6d86a (diff)
Event: Kitchener-Waterloo Hackathon 202406 Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'compat')
-rw-r--r--compat/arc4random.c398
-rw-r--r--compat/arc4random.h2
-rw-r--r--compat/arc4random_uniform.c8
-rw-r--r--compat/chacha_private.h222
-rw-r--r--compat/closefrom.c77
-rw-r--r--compat/closefrom.h24
-rw-r--r--compat/crypt/md5.h2
-rw-r--r--compat/crypt_openssl/hmac.c55
-rw-r--r--compat/crypt_openssl/hmac.h35
-rw-r--r--compat/crypt_openssl/sha256.c56
-rw-r--r--compat/crypt_openssl/sha256.h46
-rw-r--r--compat/pidfile.c6
-rw-r--r--compat/rb.c12
-rw-r--r--compat/strlcpy.c4
14 files changed, 808 insertions, 139 deletions
diff --git a/compat/arc4random.c b/compat/arc4random.c
index 90098127c954..d61d61ffa788 100644
--- a/compat/arc4random.c
+++ b/compat/arc4random.c
@@ -1,173 +1,317 @@
+/* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $ */
+
/*
- * Arc4 random number generator for OpenBSD.
- * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@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
+ * copyright notice and this permission notice appear in all copies.
*
- * Modification and redistribution in source and binary forms is
- * permitted provided that due credit is given to the author and the
- * OpenBSD project by leaving this copyright notice intact.
+ * 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.
*/
/*
- * 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.
- *
- * Here the stream cipher has been modified always to include the time
- * when initializing the state. That makes it impossible to
- * regenerate the same random sequence twice, so this can't be used
- * for encryption, but will generate good random numbers.
- *
- * RC4 is a registered trademark of RSA Laboratories.
+ * ChaCha based random number generator for OpenBSD.
*/
-#include <sys/time.h>
+/*
+ * OPENBSD ORIGINAL: lib/libc/crypt/arc4random.c
+ * lib/libc/crypt/arc4random.h
+ */
+
+#include "config.h"
#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
-#include "arc4random.h"
+#if defined(HAVE_OPENSSL)
+#include <openssl/rand.h>
+#endif
-struct arc4_stream {
- uint8_t i;
- uint8_t j;
- uint8_t s[256];
- size_t count;
- pid_t stir_pid;
- int fd;
-};
+#define KEYSTREAM_ONLY
+#include "chacha_private.h"
-#define S(n) (n)
-#define S4(n) S(n), S(n + 1), S(n + 2), S(n + 3)
-#define S16(n) S4(n), S4(n + 4), S4(n + 8), S4(n + 12)
-#define S64(n) S16(n), S16(n + 16), S16(n + 32), S16(n + 48)
-#define S256 S64(0), S64(64), S64(128), S64(192)
+#define minimum(a, b) ((a) < (b) ? (a) : (b))
-static struct arc4_stream rs = { .i = 0xff, .j = 0, .s = { S256 },
- .count = 0, .stir_pid = 0, .fd = -1 };
+#if defined(__GNUC__) || defined(_MSC_VER)
+#define inline __inline
+#else /* __GNUC__ || _MSC_VER */
+#define inline
+#endif /* !__GNUC__ && !_MSC_VER */
-#undef S
-#undef S4
-#undef S16
-#undef S64
-#undef S256
+#define KEYSZ 32
+#define IVSZ 8
+#define BLOCKSZ 64
+#define RSBUFSZ (16*BLOCKSZ)
-static void
-arc4_addrandom(struct arc4_stream *as, unsigned char *dat, int datlen)
+#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
+
+/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
+static struct _rs {
+ size_t rs_have; /* valid bytes at end of rs_buf */
+ size_t rs_count; /* bytes till reseed */
+} *rs;
+
+/* Maybe be preserved in fork children, if _rs_allocate() decides. */
+static struct _rsx {
+ chacha_ctx rs_chacha; /* chacha context for random keystream */
+ u_char rs_buf[RSBUFSZ]; /* keystream blocks */
+} *rsx;
+
+static int _dhcpcd_rand_fd = -1; /* /dev/urandom fd */
+
+static int _dhcpcd_getentropy(void *, size_t);
+static inline int _rs_allocate(struct _rs **, struct _rsx **);
+
+/* dhcpcd needs to hold onto the fd at fork due to privsep */
+#if 0
+static inline void _rs_forkdetect(void);
+#else
+#define _rs_forkdetect()
+#define _rs_forkhandler()
+#endif
+
+/* Inline "arc4random.h" */
+#include <sys/types.h>
+#include <sys/mman.h>
+
+static inline void _rs_rekey(u_char *dat, size_t datlen);
+
+/* dhcpcd isn't multithreaded */
+#define _ARC4_LOCK()
+#define _ARC4_UNLOCK()
+
+static int
+_dhcpcd_getentropy(void *buf, size_t length)
+{
+ struct timeval tv;
+ uint8_t *rand = (uint8_t *)buf;
+
+#if defined (HAVE_OPENSSL)
+ if (RAND_priv_bytes(buf, (int)length) == 1)
+ return (0);
+#endif
+
+ if (length < sizeof(tv)) {
+ gettimeofday(&tv, NULL);
+ memcpy(buf, &tv, sizeof(tv));
+ length -= sizeof(tv);
+ rand += sizeof(tv);
+ }
+ if (_dhcpcd_rand_fd == -1)
+ _dhcpcd_rand_fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK);
+ if (_dhcpcd_rand_fd != -1) {
+ /* coverity[check_return] */
+ (void)read(_dhcpcd_rand_fd, rand, length);
+ }
+
+ /* Never fail. If there is an error reading from /dev/urandom,
+ * just use what is on the stack. */
+ return (0);
+}
+
+static inline void
+_getentropy_fail(void)
+{
+ raise(SIGKILL);
+}
+
+#if 0
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+ _rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
{
- int n;
- uint8_t si;
-
- as->i--;
- for (n = 0; n < 256; n++) {
- as->i = (uint8_t)(as->i + 1);
- si = as->s[as->i];
- as->j = (uint8_t)(as->j + si + dat[n % datlen]);
- as->s[as->i] = as->s[as->j];
- as->s[as->j] = si;
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* XXX unusual calls to clone() can bypass checks */
+ if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
+ _rs_pid = pid;
+ _rs_forked = 0;
+ if (rs)
+ memset(rs, 0, sizeof(*rs));
}
- as->j = as->i;
}
+#endif
-static uint8_t
-arc4_getbyte(struct arc4_stream *as)
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
- uint8_t si, sj;
-
- as->i = (uint8_t)(as->i + 1);
- si = as->s[as->i];
- as->j = (uint8_t)(as->j + si);
- sj = as->s[as->j];
- as->s[as->i] = sj;
- as->s[as->j] = si;
- return (as->s[(si + sj) & 0xff]);
+ if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (-1);
+
+ if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+ munmap(*rsp, sizeof(**rsp));
+ *rsp = NULL;
+ return (-1);
+ }
+
+ _rs_forkhandler();
+ return (0);
}
-static uint32_t
-arc4_getword(struct arc4_stream *as)
+static inline void
+_rs_init(u_char *buf, size_t n)
{
- int val;
+ if (n < KEYSZ + IVSZ)
+ return;
+
+ if (rs == NULL) {
+ if (_rs_allocate(&rs, &rsx) == -1)
+ _exit(1);
+ }
- val = (int)((unsigned int)arc4_getbyte(as) << 24);
- val |= arc4_getbyte(as) << 16;
- val |= arc4_getbyte(as) << 8;
- val |= arc4_getbyte(as);
- return (uint32_t)val;
+ chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
+ chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
}
-/* We don't care about any error on read, just use what we have
- * on the stack. So mask off this GCC warning. */
-#pragma GCC diagnostic ignored "-Wunused-result"
static void
-arc4_stir(struct arc4_stream *as)
+_rs_stir(void)
{
- struct {
- struct timeval tv;
- unsigned int rnd[(128 - sizeof(struct timeval)) /
- sizeof(unsigned int)];
- } rdat;
- size_t n;
-
- gettimeofday(&rdat.tv, NULL);
- if (as->fd == -1) {
-#ifndef O_CLOEXEC
- int fd_opts;
-#endif
+ u_char rnd[KEYSZ + IVSZ];
+ uint32_t rekey_fuzz = 0;
- as->fd = open("/dev/urandom", O_RDONLY | O_NONBLOCK
-#ifdef O_CLOEXEC
- | O_CLOEXEC
+ if (_dhcpcd_getentropy(rnd, sizeof rnd) == -1)
+ _getentropy_fail();
+
+ if (!rs)
+ _rs_init(rnd, sizeof(rnd));
+ else
+ _rs_rekey(rnd, sizeof(rnd));
+#if defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
+#elif defined(HAVE_MEMSET_EXPLICIT)
+ (void)memset_explicit(rnd, 0, sizeof(rnd));
+#elif defined(HAVE_MEMSET_S)
+ (void)memset_s(rnd, sizeof(rnd), 0, sizeof(rnd));
+#else
+#warning potentially insecure use of memset discarding the source seed
+ (void)memset(rnd, 0, sizeof(rnd)); /* discard source seed */
#endif
- );
-#ifndef O_CLOEXEC
- if (as->fd != -1 &&
- (fd_opts = fcntl(as->fd, F_GETFD)))
- fcntl(as->fd, F_SETFD, fd_opts | FD_CLOEXEC);
+
+ /* invalidate rs_buf */
+ rs->rs_have = 0;
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+
+ /* rekey interval should not be predictable */
+ chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
+ (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
+ rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
+}
+
+static inline void
+_rs_stir_if_needed(size_t len)
+{
+ _rs_forkdetect();
+ if (!rs || rs->rs_count <= len)
+ _rs_stir();
+ if (rs->rs_count <= len)
+ rs->rs_count = 0;
+ else
+ rs->rs_count -= len;
+}
+
+static inline void
+_rs_rekey(u_char *dat, size_t datlen)
+{
+#ifndef KEYSTREAM_ONLY
+ memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
#endif
- }
+ /* fill rs_buf with the keystream */
+ chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
+ rsx->rs_buf, sizeof(rsx->rs_buf));
+ /* mix in optional user provided data */
+ if (dat) {
+ size_t i, m;
- if (as->fd != -1) {
- /* If there is an error reading, just use what is
- * on the stack. */
- /* coverity[check_return] */
- (void)read(as->fd, rdat.rnd, sizeof(rdat.rnd));
+ m = minimum(datlen, KEYSZ + IVSZ);
+ for (i = 0; i < m; i++)
+ rsx->rs_buf[i] ^= dat[i];
}
+ /* immediately reinit for backtracking resistance */
+ _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
+ memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
+ rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
+}
- /* fd < 0? Ah, what the heck. We'll just take
- * whatever was on the stack... */
- /* coverity[uninit_use_in_call] */
- arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
-
- /*
- * Throw away the first N words of output, as suggested in the
- * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
- * by Fluher, Mantin, and Shamir. (N = 256 in our case.)
- */
- for (n = 0; n < 256 * sizeof(uint32_t); n++)
- arc4_getbyte(as);
- as->count = 1600000;
+static inline void
+_rs_random_buf(void *_buf, size_t n)
+{
+ u_char *buf = (u_char *)_buf;
+ u_char *keystream;
+ size_t m;
+
+ _rs_stir_if_needed(n);
+ while (n > 0) {
+ if (rs->rs_have > 0) {
+ m = minimum(n, rs->rs_have);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
+ - rs->rs_have;
+ memcpy(buf, keystream, m);
+ memset(keystream, 0, m);
+ buf += m;
+ n -= m;
+ rs->rs_have -= m;
+ }
+ if (rs->rs_have == 0)
+ _rs_rekey(NULL, 0);
+ }
}
-static void
-arc4_stir_if_needed(struct arc4_stream *as)
+static inline void
+_rs_random_u32(uint32_t *val)
{
- pid_t pid;
-
- pid = getpid();
- if (as->count <= sizeof(uint32_t) || as->stir_pid != pid) {
- as->stir_pid = pid;
- arc4_stir(as);
- } else
- as->count -= sizeof(uint32_t);
+ u_char *keystream;
+
+ _rs_stir_if_needed(sizeof(*val));
+ if (rs->rs_have < sizeof(*val))
+ _rs_rekey(NULL, 0);
+ keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
+ memcpy(val, keystream, sizeof(*val));
+ memset(keystream, 0, sizeof(*val));
+ rs->rs_have -= sizeof(*val);
}
uint32_t
-arc4random()
+arc4random(void)
{
+ uint32_t val;
+
+ _ARC4_LOCK();
+ _rs_random_u32(&val);
+ _ARC4_UNLOCK();
+ return val;
+}
- arc4_stir_if_needed(&rs);
- return arc4_getword(&rs);
+void
+arc4random_buf(void *buf, size_t n)
+{
+ _ARC4_LOCK();
+ _rs_random_buf(buf, n);
+ _ARC4_UNLOCK();
}
diff --git a/compat/arc4random.h b/compat/arc4random.h
index a975fef3cd1b..ea1d6369235b 100644
--- a/compat/arc4random.h
+++ b/compat/arc4random.h
@@ -13,4 +13,6 @@
#include <stdint.h>
uint32_t arc4random(void);
+void arc4random_buf(void *, size_t);
+
#endif
diff --git a/compat/arc4random_uniform.c b/compat/arc4random_uniform.c
index 0f1b7b296759..4511722909b3 100644
--- a/compat/arc4random_uniform.c
+++ b/compat/arc4random_uniform.c
@@ -1,3 +1,5 @@
+/* $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $ */
+
/*
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
*
@@ -48,9 +50,11 @@ arc4random_uniform(uint32_t upper_bound)
* number inside the range we need, so it should rarely need
* to re-roll.
*/
- do
+ for (;;) {
r = arc4random();
- while (r < min);
+ if (r >= min)
+ break;
+ }
return r % upper_bound;
}
diff --git a/compat/chacha_private.h b/compat/chacha_private.h
new file mode 100644
index 000000000000..b0427b6b3e86
--- /dev/null
+++ b/compat/chacha_private.h
@@ -0,0 +1,222 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker 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)
+{
+ 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
+ }
+}
diff --git a/compat/closefrom.c b/compat/closefrom.c
new file mode 100644
index 000000000000..7161573e76b5
--- /dev/null
+++ b/compat/closefrom.c
@@ -0,0 +1,77 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * 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.
+ */
+
+#include "config.h"
+
+#ifdef __linux__
+# include <sys/syscall.h>
+# if defined(__NR_close_range) && !defined(SYS_close_range)
+# define SYS_close_range __NR_close_range
+# endif
+#endif
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#if defined(__linux__) && defined(SYS_close_range)
+static inline int
+sys_close_range(unsigned int fd, unsigned int max_fd, unsigned int flags)
+{
+
+ return (int)syscall(SYS_close_range, fd, max_fd, flags);
+}
+#endif
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ * This is the expensive (fallback) method.
+ */
+static int
+closefrom_fallback(int lowfd)
+{
+ int fd, maxfd;
+
+#ifdef _SC_OPEN_MAX
+ maxfd = (int)sysconf(_SC_OPEN_MAX);
+#else
+ maxfd = getdtablesize();
+#endif
+ if (maxfd == -1)
+ return -1;
+
+ for (fd = lowfd; fd < maxfd; fd++)
+ close(fd);
+ return 0;
+}
+
+/*
+ * * Close all file descriptors greater than or equal to lowfd.
+ * * We try the fast way first, falling back on the slow method.
+ * */
+void
+closefrom(int lowfd)
+{
+
+#if defined(__linux__) && defined(SYS_close_range)
+ if (sys_close_range((unsigned int)lowfd, UINT_MAX, 0) == 0)
+ return;
+#endif
+
+ closefrom_fallback(lowfd);
+}
diff --git a/compat/closefrom.h b/compat/closefrom.h
new file mode 100644
index 000000000000..70ce71f6bd63
--- /dev/null
+++ b/compat/closefrom.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018
+ * Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * 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.
+ */
+#ifndef CLOSEFROM_H
+#define CLOSEFROM_H
+
+void closefrom(int);
+
+#endif
diff --git a/compat/crypt/md5.h b/compat/crypt/md5.h
index dd156163315c..402309c33ae6 100644
--- a/compat/crypt/md5.h
+++ b/compat/crypt/md5.h
@@ -19,7 +19,7 @@
#define MD5_H_
#define MD5_DIGEST_LENGTH 16
-#define MD5_BLOCK_LENGTH 64ULL
+#define MD5_BLOCK_LENGTH 64
typedef struct MD5Context {
uint32_t state[4]; /* state (ABCD) */
diff --git a/compat/crypt_openssl/hmac.c b/compat/crypt_openssl/hmac.c
new file mode 100644
index 000000000000..5f55cc30b105
--- /dev/null
+++ b/compat/crypt_openssl/hmac.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2023 Canonical Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#include "openssl/hmac.h"
+
+ssize_t
+hmac(const char *name,
+ const void *key, size_t klen,
+ const void *text, size_t tlen,
+ void *digest, size_t dlen)
+{
+ const EVP_MD *md;
+ unsigned int outlen;
+
+ if (strcmp(name, "md5") == 0)
+ md = EVP_md5();
+ else if (strcmp(name, "sha256") == 0)
+ md = EVP_sha1();
+ else
+ return -1;
+
+ HMAC(md, key, (int)klen, text, tlen, digest, &outlen);
+ if (dlen != outlen)
+ return -1;
+
+ return (ssize_t)outlen;
+}
diff --git a/compat/crypt_openssl/hmac.h b/compat/crypt_openssl/hmac.h
new file mode 100644
index 000000000000..5729ed5b31fa
--- /dev/null
+++ b/compat/crypt_openssl/hmac.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2023 Canonical Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HMAC_H
+#define HMAC_H
+
+#include <sys/types.h>
+
+ssize_t hmac(const char *, const void *, size_t, const void *, size_t, void *,
+ size_t);
+
+#endif
diff --git a/compat/crypt_openssl/sha256.c b/compat/crypt_openssl/sha256.c
new file mode 100644
index 000000000000..a1595835d2fe
--- /dev/null
+++ b/compat/crypt_openssl/sha256.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2023 Canonical Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "sha256.h"
+
+#include "openssl/evp.h"
+
+/* SHA-256 initialization. Begins a SHA-256 operation. */
+void
+dhcpcd_SHA256_Init(SHA256_CTX *ctx)
+{
+ ctx->c = EVP_MD_CTX_new();
+ EVP_DigestInit_ex2(ctx->c, EVP_sha256(), NULL);
+}
+
+/* Add bytes into the hash */
+void
+dhcpcd_SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len)
+{
+ EVP_DigestUpdate(ctx->c, in, len);
+}
+
+/*
+ * SHA-256 finalization. Pads the input data, exports the hash value,
+ * and clears the context state.
+ */
+void
+dhcpcd_SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+ EVP_DigestFinal_ex(ctx->c, digest, NULL);
+ EVP_MD_CTX_free(ctx->c);
+}
diff --git a/compat/crypt_openssl/sha256.h b/compat/crypt_openssl/sha256.h
new file mode 100644
index 000000000000..74fabab7e76c
--- /dev/null
+++ b/compat/crypt_openssl/sha256.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2023 Canonical Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define SHA256_DIGEST_LENGTH 32
+
+#include "openssl/evp.h"
+typedef struct dhcpcd_SHA256Context {
+ EVP_MD_CTX *c;
+} dhcpcd_SHA256_CTX;
+
+void dhcpcd_SHA256_Init(dhcpcd_SHA256_CTX *);
+void dhcpcd_SHA256_Update(dhcpcd_SHA256_CTX *, const void *, size_t);
+void dhcpcd_SHA256_Final(unsigned char [32], dhcpcd_SHA256_CTX *);
+
+#define SHA256_Init dhcpcd_SHA256_Init
+#define SHA256_Update dhcpcd_SHA256_Update
+#define SHA256_Final dhcpcd_SHA256_Final
+#define SHA256_CTX dhcpcd_SHA256_CTX
+
+#endif
diff --git a/compat/pidfile.c b/compat/pidfile.c
index 9dfd9c468a7a..8d2e5a838c0e 100644
--- a/compat/pidfile.c
+++ b/compat/pidfile.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pidfile.c,v 1.14 2016/04/12 20:40:43 roy Exp $ */
+/* $NetBSD: pidfile.c,v 1.16 2021/08/01 15:29:29 andvar Exp $ */
/*-
* Copyright (c) 1999, 2016 The NetBSD Foundation, Inc.
@@ -131,7 +131,7 @@ pidfile_varrun_path(char *path, size_t len, const char *bname)
}
/* Returns the process ID inside path on success, otherwise -1.
- * If no path is given, use the last pidfile path, othewise the default one. */
+ * If no path is given, use the last pidfile path, otherwise the default one. */
pid_t
pidfile_read(const char *path)
{
@@ -239,7 +239,7 @@ return_pid:
if (errno == EAGAIN) {
/* The pidfile is locked, return the process ID
* it contains.
- * If sucessful, set errno to EEXIST. */
+ * If successful, set errno to EEXIST. */
if ((pid = pidfile_read(path)) != -1)
errno = EEXIST;
} else
diff --git a/compat/rb.c b/compat/rb.c
index 3c0bed5f70d5..4dfbd0d29212 100644
--- a/compat/rb.c
+++ b/compat/rb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rb.c,v 1.14 2019/03/08 09:14:54 roy Exp $ */
+/* $NetBSD: rb.c,v 1.16 2021/09/16 21:29:41 andvar Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -32,6 +32,10 @@
#include "config.h"
#include "common.h"
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/types.h>
#include <stddef.h>
@@ -44,10 +48,10 @@
#define KASSERT(s) do { } while (/*CONSTCOND*/ 0)
#define __rbt_unused __unused
#endif
-__RCSID("$NetBSD: rb.c,v 1.14 2019/03/08 09:14:54 roy Exp $");
+__RCSID("$NetBSD: rb.c,v 1.16 2021/09/16 21:29:41 andvar Exp $");
#else
#include <lib/libkern/libkern.h>
-__KERNEL_RCSID(0, "$NetBSD: rb.c,v 1.14 2019/03/08 09:14:54 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rb.c,v 1.16 2021/09/16 21:29:41 andvar Exp $");
#ifndef DIAGNOSTIC
#define __rbt_unused __unused
#else
@@ -312,7 +316,7 @@ rb_tree_insert_node(struct rb_tree *rbt, void *object)
KASSERT(rb_tree_check_node(rbt, self, NULL, true));
}
- /* Succesfully inserted, return our node pointer. */
+ /* Successfully inserted, return our node pointer. */
return object;
}
diff --git a/compat/strlcpy.c b/compat/strlcpy.c
index 1fb4a2f9615d..eceb4b4c05df 100644
--- a/compat/strlcpy.c
+++ b/compat/strlcpy.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: strlcpy.c,v 1.15 2016/10/16 17:37:39 dtucker Exp $ */
+/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */
/*
- * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@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