1 1.1 jdc /* 2 1.1 jdc __ __ _ 3 1.1 jdc ___\ \/ /_ __ __ _| |_ 4 1.1 jdc / _ \\ /| '_ \ / _` | __| 5 1.1 jdc | __// \| |_) | (_| | |_ 6 1.1 jdc \___/_/\_\ .__/ \__,_|\__| 7 1.1 jdc |_| XML parser 8 1.1 jdc 9 1.1 jdc Copyright (c) 2017-2026 Sebastian Pipping <sebastian (at) pipping.org> 10 1.1 jdc Copyright (c) 2026 Matthew Fernandez <matthew.fernandez (at) gmail.com> 11 1.1 jdc Licensed under the MIT license: 12 1.1 jdc 13 1.1 jdc Permission is hereby granted, free of charge, to any person obtaining 14 1.1 jdc a copy of this software and associated documentation files (the 15 1.1 jdc "Software"), to deal in the Software without restriction, including 16 1.1 jdc without limitation the rights to use, copy, modify, merge, publish, 17 1.1 jdc distribute, sublicense, and/or sell copies of the Software, and to permit 18 1.1 jdc persons to whom the Software is furnished to do so, subject to the 19 1.1 jdc following conditions: 20 1.1 jdc 21 1.1 jdc The above copyright notice and this permission notice shall be included 22 1.1 jdc in all copies or substantial portions of the Software. 23 1.1 jdc 24 1.1 jdc THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 1.1 jdc EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 1.1 jdc MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 1.1 jdc NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 1.1 jdc DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 1.1 jdc OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 1.1 jdc USE OR OTHER DEALINGS IN THE SOFTWARE. 31 1.1.1.3 nia 32 1.1.1.3 nia SPDX-License-Identifier: MIT 33 1.1 jdc */ 34 1.1 jdc 35 1.1 jdc #include "random_dev_urandom.h" 36 1.1 jdc 37 1.1 jdc #if ! defined(_POSIX_C_SOURCE) \ 38 1.1 jdc || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 200809L)) 39 1.1 jdc # define _POSIX_C_SOURCE 200809L // for O_CLOEXEC 40 1.1 jdc #endif 41 1.1 jdc 42 1.1 jdc #include <errno.h> 43 1.1 jdc #include <fcntl.h> // open 44 1.1 jdc #include <unistd.h> // close 45 1.1 jdc 46 1.1 jdc /* Extract entropy from /dev/urandom */ 47 1.1 jdc bool 48 1.1 jdc writeRandomBytes_dev_urandom(void *target, size_t count) { 49 1.1 jdc int success = false; /* full count bytes written? */ 50 1.1 jdc size_t bytesWrittenTotal = 0; 51 1.1 jdc 52 1.1 jdc const int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); 53 1.1 jdc if (fd < 0) { 54 1.1.1.2 jdc return false; 55 1.1 jdc } 56 1.1 jdc 57 1.1 jdc do { 58 1.1.1.2 jdc void *const currentTarget = (char *)target + bytesWrittenTotal; 59 1.1 jdc const size_t bytesToWrite = count - bytesWrittenTotal; 60 1.1 jdc 61 1.1 jdc errno = 0; 62 1.1 jdc 63 1.1 jdc const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); 64 1.1 jdc 65 1.1 jdc if (bytesWrittenMore > 0) { 66 1.1 jdc bytesWrittenTotal += bytesWrittenMore; 67 1.1 jdc if (bytesWrittenTotal >= count) 68 1.1 jdc success = true; 69 1.1 jdc } 70 1.1 jdc } while (! success && (errno == EINTR)); 71 1.1 jdc 72 1.1 jdc close(fd); 73 1.1 jdc return success; 74 1.1 jdc } 75