Coverage Report

Created: 2025-12-31 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/hcrypto/rand-unix.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2006 Kungliga Tekniska Högskolan
3
 * (Royal Institute of Technology, Stockholm, Sweden).
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * 3. Neither the name of the Institute nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include <config.h>
35
#include <roken.h>
36
37
#include <rand.h>
38
#include <heim_threads.h>
39
40
#include "randi.h"
41
42
/*
43
 * Unix /dev/random
44
 */
45
46
int
47
_hc_unix_device_fd(int flags, const char **fn)
48
0
{
49
0
    static const char *rnd_devices[] = {
50
0
  "/dev/urandom",
51
0
  "/dev/random",
52
0
  "/dev/srandom",
53
0
  "/dev/arandom",
54
0
  NULL
55
0
    };
56
0
    const char **p;
57
58
0
    for(p = rnd_devices; *p; p++) {
59
0
  int fd = open(*p, flags | O_NDELAY);
60
0
  if(fd >= 0) {
61
0
      if (fn)
62
0
    *fn = *p;
63
0
      rk_cloexec(fd);
64
0
      return fd;
65
0
  }
66
0
    }
67
0
    return -1;
68
0
}
69
70
static void
71
unix_seed(const void *p, int size)
72
0
{
73
0
    const unsigned char *indata = p;
74
0
    ssize_t count;
75
0
    int fd;
76
77
0
    if (size < 0)
78
0
  return;
79
0
    else if (size == 0)
80
0
  return;
81
82
0
    fd = _hc_unix_device_fd(O_RDONLY, NULL);
83
0
    if (fd < 0)
84
0
  return;
85
86
0
    while (size > 0) {
87
0
  count = write(fd, indata, size);
88
0
  if (count < 0 && errno == EINTR)
89
0
      continue;
90
0
  else if (count <= 0) {
91
0
      close(fd);
92
0
      return;
93
0
  }
94
0
  indata += count;
95
0
  size -= count;
96
0
    }
97
0
    close(fd);
98
0
}
99
100
101
static int
102
unix_bytes(unsigned char *outdata, int size)
103
0
{
104
0
    ssize_t count;
105
0
    int fd;
106
107
0
    if (size < 0)
108
0
  return 0;
109
0
    else if (size == 0)
110
0
  return 1;
111
112
0
    fd = _hc_unix_device_fd(O_RDONLY, NULL);
113
0
    if (fd < 0)
114
0
  return 0;
115
116
0
    while (size > 0) {
117
0
  count = read(fd, outdata, size);
118
0
  if (count < 0 && errno == EINTR)
119
0
      continue;
120
0
  else if (count <= 0) {
121
0
      close(fd);
122
0
      return 0;
123
0
  }
124
0
  outdata += count;
125
0
  size -= count;
126
0
    }
127
0
    close(fd);
128
129
0
    return 1;
130
0
}
131
132
static void
133
unix_cleanup(void)
134
0
{
135
0
}
136
137
static void
138
unix_add(const void *indata, int size, double entropi)
139
0
{
140
0
    unix_seed(indata, size);
141
0
}
142
143
static int
144
unix_pseudorand(unsigned char *outdata, int size)
145
0
{
146
0
    return unix_bytes(outdata, size);
147
0
}
148
149
static int
150
unix_status(void)
151
0
{
152
0
    int fd;
153
154
0
    fd = _hc_unix_device_fd(O_RDONLY, NULL);
155
0
    if (fd < 0)
156
0
  return 0;
157
0
    close(fd);
158
159
0
    return 1;
160
0
}
161
162
const RAND_METHOD hc_rand_unix_method = {
163
    unix_seed,
164
    unix_bytes,
165
    unix_cleanup,
166
    unix_add,
167
    unix_pseudorand,
168
    unix_status
169
};
170
171
const RAND_METHOD *
172
RAND_unix_method(void)
173
0
{
174
0
    return &hc_rand_unix_method;
175
0
}