making it much easier for libressl -portable to fill in the gaps.
ok bcook beck
-/* $OpenBSD: arc4random.c,v 1.46 2014/07/17 14:30:41 deraadt Exp $ */
+/* $OpenBSD: arc4random.c,v 1.47 2014/07/18 02:05:55 deraadt Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
#define RSBUFSZ (16*BLOCKSZ)
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
-static struct {
+static struct _rs {
size_t rs_have; /* valid bytes at end of rs_buf */
size_t rs_count; /* bytes till reseed */
} *rs;
+static inline void *_rs_allocate(size_t len);
+static inline void _rs_forkdetect(void);
+static inline void _rs_forkdetectsetup(struct _rs *buf, size_t len);
+#include "arc4random.h"
+
/* Preserved in fork children. */
static struct {
chacha_ctx rs_chacha; /* chacha context for random keystream */
static inline void _rs_rekey(u_char *dat, size_t datlen);
-#ifndef MAP_INHERIT_ZERO
-static inline void
-_rs_forkhandler(void)
-{
- /*
- * Race-free because we're running single-threaded in a new
- * address space, and once allocated rs is never deallocated.
- */
- if (rs)
- rs->rs_count = 0;
-}
-#endif /* MAP_INHERIT_ZERO */
-
static inline void
_rs_init(u_char *buf, size_t n)
{
return;
if (rs == NULL) {
- if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
- abort();
-#ifdef MAP_INHERIT_ZERO
- if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
+ if ((rs = _rs_allocate(sizeof(*rs))) == NULL)
abort();
-#else
- _ARC4_ATFORK(_rs_forkhandler);
-#endif
+ _rs_forkdetectsetup(rs, sizeof(*rs));
}
if (rsx == NULL) {
- if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ if ((rsx = _rs_allocate(sizeof(*rsx))) == NULL)
abort();
}
static inline void
_rs_stir_if_needed(size_t len)
{
-#ifndef MAP_INHERIT_ZERO
- static pid_t _rs_pid = 0;
- pid_t pid = getpid();
-
- /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
- if (_rs_pid == 0 || _rs_pid != pid) {
- _rs_pid = pid;
- if (rs)
- rs->rs_count = 0;
- }
-#endif
+ _rs_forkdetect();
if (!rs || rs->rs_count <= len)
_rs_stir();
if (rs->rs_count <= len)
--- /dev/null
+/* $OpenBSD: arc4random.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ if (minherit(rs, len, MAP_INHERIT_ZERO) == -1)
+ abort();
+}
--- /dev/null
+/* $OpenBSD: arc4random_linux.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_osx.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_solaris.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_win.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ return calloc(1, sizeof(*rs));
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_linux.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_osx.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_solaris.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ void *p;
+
+ if ((p = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ return (NULL);
+ return (p);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+ /*
+ * Race-free because we're running single-threaded in a new
+ * address space, and once allocated rs is never deallocated.
+ */
+ if (rs)
+ rs->rs_count = 0;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+ static pid_t _rs_pid = 0;
+ pid_t pid = getpid();
+
+ /* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
+ if (_rs_pid == 0 || _rs_pid != pid) {
+ _rs_pid = pid;
+ if (rs)
+ rs->rs_count = 0;
+ }
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+ _ARC4_ATFORK(_rs_forkhandler);
+}
+
--- /dev/null
+/* $OpenBSD: arc4random_win.h,v 1.1 2014/07/18 02:05:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+static inline void *
+_rs_allocate(size_t len)
+{
+ return calloc(1, sizeof(*rs));
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+}
+
+static inline void
+_rs_forkdetectsetup(struct _rs *rs, size_t len)
+{
+}
+