Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / tls / tls_prng_dev.c
blob7a38bb3459c6e02c053a577d6c523723fd2b5372
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* tls_prng_dev 3
6 /* SUMMARY
7 /* seed OpenSSL PRNG from entropy device
8 /* SYNOPSIS
9 /* #include <tls_prng_src.h>
11 /* TLS_PRNG_SRC *tls_prng_dev_open(name, timeout)
12 /* const char *name;
13 /* int timeout;
15 /* ssize_t tls_prng_dev_read(dev, length)
16 /* TLS_PRNG_SRC *dev;
17 /* size_t length;
19 /* int tls_prng_dev_close(dev)
20 /* TLS_PRNG_SRC *dev;
21 /* DESCRIPTION
22 /* tls_prng_dev_open() opens the specified entropy device
23 /* and returns a handle that should be used with all subsequent
24 /* access.
26 /* tls_prng_dev_read() reads the requested number of bytes from
27 /* the entropy device and updates the OpenSSL PRNG.
29 /* tls_prng_dev_close() closes the specified entropy device
30 /* and releases memory that was allocated for the handle.
32 /* Arguments:
33 /* .IP name
34 /* The pathname of the entropy device.
35 /* .IP length
36 /* The number of bytes to read from the entropy device.
37 /* Request lengths will be truncated at 255 bytes.
38 /* .IP timeout
39 /* Time limit on individual I/O operations.
40 /* DIAGNOSTICS
41 /* tls_prng_dev_open() returns a null pointer on error.
43 /* tls_prng_dev_read() returns -1 on error, the number
44 /* of bytes received on success.
46 /* tls_prng_dev_close() returns -1 on error, 0 on success.
48 /* In all cases the errno variable indicates the type of error.
49 /* LICENSE
50 /* .ad
51 /* .fi
52 /* The Secure Mailer license must be distributed with this software.
53 /* AUTHOR(S)
54 /* Wietse Venema
55 /* IBM T.J. Watson Research
56 /* P.O. Box 704
57 /* Yorktown Heights, NY 10598, USA
58 /*--*/
60 /* System library. */
62 #include <sys_defs.h>
63 #include <fcntl.h>
64 #include <unistd.h>
65 #include <limits.h>
66 #include <errno.h>
68 #ifndef UCHAR_MAX
69 #define UCHAR_MAX 0xff
70 #endif
72 /* OpenSSL library. */
74 #ifdef USE_TLS
75 #include <openssl/rand.h> /* For the PRNG */
77 /* Utility library. */
79 #include <msg.h>
80 #include <mymalloc.h>
81 #include <connect.h>
82 #include <iostuff.h>
84 /* TLS library. */
86 #include <tls_prng.h>
88 /* tls_prng_dev_open - open entropy device */
90 TLS_PRNG_SRC *tls_prng_dev_open(const char *name, int timeout)
92 const char *myname = "tls_prng_dev_open";
93 TLS_PRNG_SRC *dev;
94 int fd;
96 if ((fd = open(name, O_RDONLY, 0)) < 0) {
97 if (msg_verbose)
98 msg_info("%s: cannot open entropy device %s: %m", myname, name);
99 return (0);
100 } else {
101 dev = (TLS_PRNG_SRC *) mymalloc(sizeof(*dev));
102 dev->fd = fd;
103 dev->name = mystrdup(name);
104 dev->timeout = timeout;
105 if (msg_verbose)
106 msg_info("%s: opened entropy device %s", myname, name);
107 return (dev);
111 /* tls_prng_dev_read - update internal PRNG from device */
113 ssize_t tls_prng_dev_read(TLS_PRNG_SRC *dev, size_t len)
115 const char *myname = "tls_prng_dev_read";
116 unsigned char buffer[UCHAR_MAX];
117 ssize_t count;
118 size_t rand_bytes;
120 if (len <= 0)
121 msg_panic("%s: bad read length: %ld", myname, (long) len);
123 if (len > sizeof(buffer))
124 rand_bytes = sizeof(buffer);
125 else
126 rand_bytes = len;
127 errno = 0;
128 count = timed_read(dev->fd, buffer, rand_bytes, dev->timeout, (void *) 0);
129 if (count > 0) {
130 if (msg_verbose)
131 msg_info("%s: read %ld bytes from entropy device %s",
132 myname, (long) count, dev->name);
133 RAND_seed(buffer, count);
134 } else {
135 if (msg_verbose)
136 msg_info("%s: cannot read %ld bytes from entropy device %s: %m",
137 myname, (long) rand_bytes, dev->name);
139 return (count);
142 /* tls_prng_dev_close - disconnect from EGD server */
144 int tls_prng_dev_close(TLS_PRNG_SRC *dev)
146 const char *myname = "tls_prng_dev_close";
147 int err;
149 if (msg_verbose)
150 msg_info("%s: close entropy device %s", myname, dev->name);
151 err = close(dev->fd);
152 myfree(dev->name);
153 myfree((char *) dev);
154 return (err);
157 #endif