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 2638a52bd3SEd Maste #include <sys/mman.h> 2738a52bd3SEd Maste 2838a52bd3SEd Maste #include <signal.h> 2938a52bd3SEd Maste 3038a52bd3SEd Maste /* OpenSSH isn't multithreaded */ 3138a52bd3SEd Maste #define _ARC4_LOCK() 3238a52bd3SEd Maste #define _ARC4_UNLOCK() 3338a52bd3SEd Maste #define _ARC4_ATFORK(f) 3438a52bd3SEd Maste 3538a52bd3SEd Maste static inline void 3638a52bd3SEd Maste _getentropy_fail(void) 3738a52bd3SEd Maste { 3838a52bd3SEd Maste fatal("getentropy failed"); 3938a52bd3SEd Maste } 4038a52bd3SEd Maste 4138a52bd3SEd Maste static volatile sig_atomic_t _rs_forked; 4238a52bd3SEd Maste 4338a52bd3SEd Maste static inline void 4438a52bd3SEd Maste _rs_forkhandler(void) 4538a52bd3SEd Maste { 4638a52bd3SEd Maste _rs_forked = 1; 4738a52bd3SEd Maste } 4838a52bd3SEd Maste 4938a52bd3SEd Maste static inline void 5038a52bd3SEd Maste _rs_forkdetect(void) 5138a52bd3SEd Maste { 5238a52bd3SEd Maste static pid_t _rs_pid = 0; 5338a52bd3SEd Maste pid_t pid = getpid(); 5438a52bd3SEd Maste 5538a52bd3SEd Maste if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) { 5638a52bd3SEd Maste _rs_pid = pid; 5738a52bd3SEd Maste _rs_forked = 0; 5838a52bd3SEd Maste if (rs) 5938a52bd3SEd Maste memset(rs, 0, sizeof(*rs)); 6038a52bd3SEd Maste } 6138a52bd3SEd Maste } 6238a52bd3SEd Maste 6338a52bd3SEd Maste static inline int 6438a52bd3SEd Maste _rs_allocate(struct _rs **rsp, struct _rsx **rsxp) 6538a52bd3SEd Maste { 66*f374ba41SEd Maste #if defined(MAP_ANON) && defined(MAP_PRIVATE) 6738a52bd3SEd Maste if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, 6838a52bd3SEd Maste MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) 6938a52bd3SEd Maste return (-1); 7038a52bd3SEd Maste 7138a52bd3SEd Maste if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, 7238a52bd3SEd Maste MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { 7338a52bd3SEd Maste munmap(*rsp, sizeof(**rsp)); 7438a52bd3SEd Maste *rsp = NULL; 7538a52bd3SEd Maste return (-1); 7638a52bd3SEd Maste } 77*f374ba41SEd Maste #else 78*f374ba41SEd Maste if ((*rsp = calloc(1, sizeof(**rsp))) == NULL) 79*f374ba41SEd Maste return (-1); 80*f374ba41SEd Maste if ((*rsxp = calloc(1, sizeof(**rsxp))) == NULL) { 81*f374ba41SEd Maste free(*rsp); 82*f374ba41SEd Maste *rsp = NULL; 83*f374ba41SEd Maste return (-1); 84*f374ba41SEd Maste } 85*f374ba41SEd Maste #endif 8638a52bd3SEd Maste 8738a52bd3SEd Maste _ARC4_ATFORK(_rs_forkhandler); 8838a52bd3SEd Maste return (0); 8938a52bd3SEd Maste } 90