summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-02-03 14:04:50 +1100
committerDamien Miller <djm@mindrot.org>2000-02-03 14:04:50 +1100
commit8b171bc4cd9367e9dc99e53ebabcb0d04f9ba7da (patch)
tree1a84255d580fb3381c9fe7cac218015b74c4a2e5 /random.c
parentdd777a441ff2449541ce22728021a477c8cd5f08 (diff)
Import of spilt-off random collection code
Diffstat (limited to 'random.c')
-rw-r--r--random.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/random.c b/random.c
new file mode 100644
index 000000000..06c8d2b3c
--- /dev/null
+++ b/random.c
@@ -0,0 +1,124 @@
1/*
2**
3** Random number collection
4**
5** Damien Miller <djm@ibs.com.au>
6**
7** Copyright 1999 Damien Miller
8**
9** Permission is hereby granted, free of charge, to any person
10** obtaining a copy of this software and associated documentation
11** files (the "Software"), to deal in the Software without
12** restriction, including without limitation the rights to use, copy,
13** modify, merge, publish, distribute, sublicense, and/or sell copies
14** of the Software, and to permit persons to whom the Software is
15** furnished to do so, subject to the following conditions:
16**
17** The above copyright notice and this permission notice shall be
18** included in all copies or substantial portions of the Software.
19**
20** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
21** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
22** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23** AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER OR INTERNET
24** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
27** OR OTHER DEALINGS IN THE SOFTWARE.
28**
29** Except as contained in this notice, the name of Internet Business
30** Solutions shall not be used in advertising or otherwise to promote
31** the sale, use or other dealings in this Software without prior
32** written authorization from Internet Business Solutions.
33**
34*/
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <errno.h>
40#include <unistd.h>
41
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <sys/socket.h>
45#include <sys/un.h>
46#include <fcntl.h>
47#ifdef HAVE_STDDEF_H
48#include <stddef.h>
49#endif
50
51#include "ssh.h"
52#include "xmalloc.h"
53#include "random.h"
54
55#ifndef offsetof
56# define offsetof(type, member) ((size_t) &((type *)0)->member)
57#endif
58
59#ifdef HAVE_EGD
60
61/* Collect entropy from EGD */
62void get_random_bytes(unsigned char *buf, int len)
63{
64 static int random_pool;
65 int c;
66 char egd_message[2] = { 0x02, 0x00 };
67 struct sockaddr_un addr;
68 int addr_len;
69
70 memset(&addr, '\0', sizeof(addr));
71 addr.sun_family = AF_UNIX;
72
73 /* FIXME: compile time check? */
74 if (sizeof(RANDOM_POOL) > sizeof(addr.sun_path))
75 fatal("Random pool path is too long");
76
77 strcpy(addr.sun_path, RANDOM_POOL);
78
79 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(RANDOM_POOL);
80
81 random_pool = socket(AF_UNIX, SOCK_STREAM, 0);
82
83 if (random_pool == -1)
84 fatal("Couldn't create AF_UNIX socket: %s", strerror(errno));
85
86 if (connect(random_pool, (struct sockaddr*)&addr, addr_len) == -1)
87 fatal("Couldn't connect to EGD socket \"%s\": %s", addr.sun_path, strerror(errno));
88
89 if (len > 255)
90 fatal("Too many bytes to read from EGD");
91
92 /* Send blocking read request to EGD */
93 egd_message[1] = len;
94
95 c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
96 if (c == -1)
97 fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
98
99 c = atomicio(read, random_pool, buf, len);
100 if (c <= 0)
101 fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
102
103 close(random_pool);
104}
105#else /* HAVE_EGD */
106
107/* Collect entropy from /dev/urandom or pipe */
108void get_random_bytes(unsigned char *buf, int len)
109{
110 static int random_pool;
111 int c;
112
113 random_pool = open(RANDOM_POOL, O_RDONLY);
114 if (random_pool == -1)
115 fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
116
117 c = atomicio(read, random_pool, buf, len);
118 if (c <= 0)
119 fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
120
121 close(random_pool);
122}
123
124#endif /* HAVE_EGD */