Coverage Report

Created: 2024-04-25 06:27

/src/pdns/ext/arc4random/bsd-getentropy.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
3
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
4
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include "includes.h"
20
21
#ifndef SSH_RANDOM_DEV
22
0
# define SSH_RANDOM_DEV "/dev/urandom"
23
#endif /* SSH_RANDOM_DEV */
24
25
#include <sys/types.h>
26
#ifdef HAVE_SYS_RANDOM_H
27
# include <sys/random.h>
28
#endif
29
30
#include <fcntl.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <unistd.h>
34
#ifdef WITH_OPENSSL
35
#include <openssl/rand.h>
36
#include <openssl/err.h>
37
#endif
38
39
#include "log.h"
40
41
int
42
_ssh_compat_getentropy(void *s, size_t len)
43
0
{
44
#ifdef WITH_OPENSSL
45
  if (RAND_bytes(s, len) <= 0)
46
    fatal("Couldn't obtain random bytes (error 0x%lx)",
47
        (unsigned long)ERR_get_error());
48
#else
49
0
  int fd, save_errno;
50
0
  ssize_t r;
51
0
  size_t o = 0;
52
53
0
#ifdef HAVE_GETENTROPY
54
0
  if ((r = getentropy(s, len)) == 0)
55
0
    return 0;
56
0
#endif /* HAVE_GETENTROPY */
57
0
#ifdef HAVE_GETRANDOM
58
0
  if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len)
59
0
    return 0;
60
0
#endif /* HAVE_GETRANDOM */
61
62
0
  if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) {
63
0
    save_errno = errno;
64
    /* Try egd/prngd before giving up. */
65
0
    if (seed_from_prngd(s, len) == 0)
66
0
      return 0;
67
0
    fatal("Couldn't open %s: %s", SSH_RANDOM_DEV,
68
0
        strerror(save_errno));
69
0
  }
70
0
  while (o < len) {
71
0
    r = read(fd, (u_char *)s + o, len - o);
72
0
    if (r < 0) {
73
0
      if (errno == EAGAIN || errno == EINTR ||
74
0
          errno == EWOULDBLOCK)
75
0
        continue;
76
0
      fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno));
77
0
    }
78
0
    o += r;
79
0
  }
80
0
  close(fd);
81
0
#endif /* WITH_OPENSSL */
82
0
  return 0;
83
0
}