1
/* random-daemon.c - Access to the external random daemon
2
* Copyright (C) 2006 Free Software Foundation, Inc.
4
* This file is part of Libgcrypt.
6
* Libgcrypt is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as
8
* published by the Free Software Foundation; either version 2.1 of
9
* the License, or (at your option) any later version.
11
* Libgcrypt is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22
The functions here are used by random.c to divert calls to an
23
external random number daemon. The actual daemon we use is
24
gcryptrnd. Such a daemon is useful to keep a persistent pool in
25
memory over invocations of a single application and to allow
26
prioritizing access to the actual entropy sources. The drawback is
27
that we need to use IPC (i.e. unix domain socket) to convey
37
#include <sys/socket.h>
48
/* This is default socket name we use in case the provided socket name
50
#define RANDOM_DAEMON_SOCKET "/var/run/libgcrypt/S.gcryptrnd"
52
/* The lock serializing access to the daemon. */
53
static ath_mutex_t daemon_lock = ATH_MUTEX_INITIALIZER;
55
/* The socket connected to the daemon. */
56
static int daemon_socket = -1;
58
/* Creates a socket connected to the daemon. On success, store the
59
socket fd in *SOCK. Returns error code. */
61
connect_to_socket (const char *socketname, int *sock)
63
struct sockaddr_un *srvr_addr;
71
/* Create a socket. */
72
fd = socket (AF_UNIX, SOCK_STREAM, 0);
75
log_error ("can't create socket: %s\n", strerror (errno));
76
err = gcry_error_from_errno (errno);
81
srvr_addr = gcry_malloc (sizeof *srvr_addr);
84
log_error ("malloc failed: %s\n", strerror (errno));
85
err = gcry_error_from_errno (errno);
88
memset (srvr_addr, 0, sizeof *srvr_addr);
89
srvr_addr->sun_family = AF_UNIX;
90
if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
92
log_error ("socket name `%s' too long\n", socketname);
93
err = gcry_error (GPG_ERR_ENAMETOOLONG);
96
strcpy (srvr_addr->sun_path, socketname);
97
addrlen = (offsetof (struct sockaddr_un, sun_path)
98
+ strlen (srvr_addr->sun_path) + 1);
100
/* Connect socket. */
101
rc = connect (fd, (struct sockaddr *) srvr_addr, addrlen);
104
log_error ("error connecting socket `%s': %s\n",
105
srvr_addr->sun_path, strerror (errno));
106
err = gcry_error_from_errno (errno);
114
gcry_free (srvr_addr);
126
/* Initialize basics of this module. This should be viewed as a
127
constructor to prepare locking. */
129
_gcry_daemon_initialize_basics (void)
131
static int initialized;
137
err = ath_mutex_init (&daemon_lock);
139
log_fatal ("failed to create the daemon lock: %s\n", strerror (err) );
145
/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
146
success or another value on write error. */
148
writen (int fd, const void *buffer, size_t length)
155
n = ath_write (fd, buffer, length);
156
while (n < 0 && errno == EINTR);
159
log_error ("write error: %s\n", strerror (errno));
160
return -1; /* write error */
163
buffer = (const char*)buffer + n;
169
readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
171
size_t nleft = buflen;
178
nread = ath_read (fd, buf, nleft);
189
buf = (char*)buf + nread;
192
*ret_nread = buflen - nleft;
196
/* This functions requests REQ_NBYTES from the daemon. If NONCE is
197
true, the data should be suited for a nonce. If NONCE is FALSE,
198
data of random level LEVEL will be generated. The retrieved random
199
data will be stored in BUFFER. Returns error code. */
201
call_daemon (const char *socketname,
202
void *buffer, size_t req_nbytes, int nonce,
203
enum gcry_random_level level)
205
static int initialized;
206
unsigned char buf[255];
207
gcry_error_t err = 0;
215
ath_mutex_lock (&daemon_lock);
217
/* Open the socket if that has not been done. */
221
err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET,
226
log_info ("not using random daemon\n");
227
ath_mutex_unlock (&daemon_lock);
232
/* Check that we have a valid socket descriptor. */
233
if ( daemon_socket == -1 )
235
ath_mutex_unlock (&daemon_lock);
236
return gcry_error (GPG_ERR_INTERNAL);
240
/* Do the real work. */
244
/* Process in chunks. */
245
nbytes = req_nbytes > sizeof (buf) ? sizeof (buf) : req_nbytes;
246
req_nbytes -= nbytes;
248
/* Construct request. */
252
else if (level == GCRY_VERY_STRONG_RANDOM)
254
else if (level == GCRY_STRONG_RANDOM)
259
rc = writen (daemon_socket, buf, 3);
262
err = gcry_error_from_errno (errno);
266
/* Retrieve response. */
268
rc = readn (daemon_socket, buf, 2, &nread);
271
err = gcry_error_from_errno (errno);
272
log_error ("read error: %s\n", gcry_strerror (err));
277
log_error ("random daemon returned error code %d\n", buf[0]);
278
err = gcry_error (GPG_ERR_INTERNAL); /* ? */
283
log_error ("response too small\n");
284
err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
288
/* if (1)*/ /* Do this in verbose mode? */
289
/* log_info ("received response with %d bytes of data\n", buf[1]);*/
293
log_error ("error: server returned less bytes than requested\n");
294
err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
297
else if (buf[1] > nbytes)
299
log_error ("warning: server returned more bytes than requested\n");
300
err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
304
assert (nbytes <= sizeof (buf));
306
rc = readn (daemon_socket, buf, nbytes, &nread);
309
err = gcry_error_from_errno (errno);
310
log_error ("read error: %s\n", gcry_strerror (err));
316
log_error ("too little random data read\n");
317
err = gcry_error (GPG_ERR_INTERNAL);
321
/* Successfuly read another chunk of data. */
322
memcpy (buffer, buf, nbytes);
323
buffer = ((char *) buffer) + nbytes;
327
ath_mutex_unlock (&daemon_lock);
332
/* Internal function to fill BUFFER with LENGTH bytes of random. We
333
support GCRY_STRONG_RANDOM and GCRY_VERY_STRONG_RANDOM here.
334
Return 0 on success. */
336
_gcry_daemon_randomize (const char *socketname,
337
void *buffer, size_t length,
338
enum gcry_random_level level)
342
err = call_daemon (socketname, buffer, length, 0, level);
348
/* Internal function to fill BUFFER with NBYTES of data usable for a
349
nonce. Returns 0 on success. */
351
_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length)
355
err = call_daemon (socketname, buffer, length, 1, 0);