Home | History | Annotate | Line # | Download | only in lib
      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