138a52bd3SEd Maste /* $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $ */
238a52bd3SEd Maste
338a52bd3SEd Maste /*
438a52bd3SEd Maste * Copyright (c) 1996, David Mazieres <dm@uun.org>
538a52bd3SEd Maste * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
638a52bd3SEd Maste * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
738a52bd3SEd Maste * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
838a52bd3SEd Maste *
938a52bd3SEd Maste * Permission to use, copy, modify, and distribute this software for any
1038a52bd3SEd Maste * purpose with or without fee is hereby granted, provided that the above
1138a52bd3SEd Maste * copyright notice and this permission notice appear in all copies.
1238a52bd3SEd Maste *
1338a52bd3SEd Maste * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1438a52bd3SEd Maste * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1538a52bd3SEd Maste * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1638a52bd3SEd Maste * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1738a52bd3SEd Maste * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1838a52bd3SEd Maste * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1938a52bd3SEd Maste * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2038a52bd3SEd Maste */
2138a52bd3SEd Maste
2238a52bd3SEd Maste /*
2338a52bd3SEd Maste * Stub functions for portability. From LibreSSL with some adaptations.
2438a52bd3SEd Maste */
2538a52bd3SEd Maste
26*3d9fd9fcSEd Maste #ifdef HAVE_SYS_MMAN_H
2738a52bd3SEd Maste #include <sys/mman.h>
28*3d9fd9fcSEd Maste #endif
2938a52bd3SEd Maste
3038a52bd3SEd Maste #include <signal.h>
3138a52bd3SEd Maste
3238a52bd3SEd Maste /* OpenSSH isn't multithreaded */
3338a52bd3SEd Maste #define _ARC4_LOCK()
3438a52bd3SEd Maste #define _ARC4_UNLOCK()
3538a52bd3SEd Maste #define _ARC4_ATFORK(f)
3638a52bd3SEd Maste
3738a52bd3SEd Maste static inline void
_getentropy_fail(void)3838a52bd3SEd Maste _getentropy_fail(void)
3938a52bd3SEd Maste {
4038a52bd3SEd Maste fatal("getentropy failed");
4138a52bd3SEd Maste }
4238a52bd3SEd Maste
4338a52bd3SEd Maste static volatile sig_atomic_t _rs_forked;
4438a52bd3SEd Maste
4538a52bd3SEd Maste static inline void
_rs_forkhandler(void)4638a52bd3SEd Maste _rs_forkhandler(void)
4738a52bd3SEd Maste {
4838a52bd3SEd Maste _rs_forked = 1;
4938a52bd3SEd Maste }
5038a52bd3SEd Maste
5138a52bd3SEd Maste static inline void
_rs_forkdetect(void)5238a52bd3SEd Maste _rs_forkdetect(void)
5338a52bd3SEd Maste {
5438a52bd3SEd Maste static pid_t _rs_pid = 0;
5538a52bd3SEd Maste pid_t pid = getpid();
5638a52bd3SEd Maste
5738a52bd3SEd Maste if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
5838a52bd3SEd Maste _rs_pid = pid;
5938a52bd3SEd Maste _rs_forked = 0;
6038a52bd3SEd Maste if (rs)
6138a52bd3SEd Maste memset(rs, 0, sizeof(*rs));
6238a52bd3SEd Maste }
6338a52bd3SEd Maste }
6438a52bd3SEd Maste
6538a52bd3SEd Maste static inline int
_rs_allocate(struct _rs ** rsp,struct _rsx ** rsxp)6638a52bd3SEd Maste _rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
6738a52bd3SEd Maste {
68f374ba41SEd Maste #if defined(MAP_ANON) && defined(MAP_PRIVATE)
6938a52bd3SEd Maste if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
7038a52bd3SEd Maste MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
7138a52bd3SEd Maste return (-1);
7238a52bd3SEd Maste
7338a52bd3SEd Maste if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
7438a52bd3SEd Maste MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
7538a52bd3SEd Maste munmap(*rsp, sizeof(**rsp));
7638a52bd3SEd Maste *rsp = NULL;
7738a52bd3SEd Maste return (-1);
7838a52bd3SEd Maste }
79f374ba41SEd Maste #else
80f374ba41SEd Maste if ((*rsp = calloc(1, sizeof(**rsp))) == NULL)
81f374ba41SEd Maste return (-1);
82f374ba41SEd Maste if ((*rsxp = calloc(1, sizeof(**rsxp))) == NULL) {
83f374ba41SEd Maste free(*rsp);
84f374ba41SEd Maste *rsp = NULL;
85f374ba41SEd Maste return (-1);
86f374ba41SEd Maste }
87f374ba41SEd Maste #endif
8838a52bd3SEd Maste
8938a52bd3SEd Maste _ARC4_ATFORK(_rs_forkhandler);
9038a52bd3SEd Maste return (0);
9138a52bd3SEd Maste }
92