1/*++
2/* NAME
3/*	tls_prng_exch 3
4/* SUMMARY
5/*	maintain PRNG exchange file
6/* SYNOPSIS
7/*	#include <tls_prng_src.h>
8/*
9/*	TLS_PRNG_SRC *tls_prng_exch_open(name, timeout)
10/*	const char *name;
11/*	int	timeout;
12/*
13/*	void	tls_prng_exch_update(fh, length)
14/*	TLS_PRNG_SRC *fh;
15/*	size_t length;
16/*
17/*	void	tls_prng_exch_close(fh)
18/*	TLS_PRNG_SRC *fh;
19/* DESCRIPTION
20/*	tls_prng_exch_open() opens the specified PRNG exchange file
21/*	and returns a handle that should be used with all subsequent
22/*	access.
23/*
24/*	tls_prng_exch_update() reads the requested number of bytes
25/*	from the PRNG exchange file, updates the OpenSSL PRNG, and
26/*	writes the requested number of bytes to the exchange file.
27/*	The file is locked for exclusive access.
28/*
29/*	tls_prng_exch_close() closes the specified PRNG exchange
30/*	file and releases memory that was allocated for the handle.
31/*
32/*	Arguments:
33/* .IP name
34/*	The name of the PRNG exchange file.
35/* .IP length
36/*	The number of bytes to read from/write to the entropy file.
37/* .IP timeout
38/*	Time limit on individual I/O operations.
39/* DIAGNOSTICS
40/*	All errors are fatal.
41/* LICENSE
42/* .ad
43/* .fi
44/*	The Secure Mailer license must be distributed with this software.
45/* AUTHOR(S)
46/*	Wietse Venema
47/*	IBM T.J. Watson Research
48/*	P.O. Box 704
49/*	Yorktown Heights, NY 10598, USA
50/*--*/
51
52/* System library. */
53
54#include <sys_defs.h>
55#include <fcntl.h>
56#include <unistd.h>
57#include <limits.h>
58
59/* OpenSSL library. */
60
61#ifdef USE_TLS
62#include <openssl/rand.h>		/* For the PRNG */
63
64/* Utility library. */
65
66#include <msg.h>
67#include <mymalloc.h>
68#include <iostuff.h>
69#include <myflock.h>
70
71/* TLS library. */
72
73#include <tls_prng.h>
74
75/* Application specific. */
76
77#define TLS_PRNG_EXCH_SIZE	1024	/* XXX Why not configurable? */
78
79/* tls_prng_exch_open - open PRNG exchange file */
80
81TLS_PRNG_SRC *tls_prng_exch_open(const char *name)
82{
83    const char *myname = "tls_prng_exch_open";
84    TLS_PRNG_SRC *eh;
85    int     fd;
86
87    if ((fd = open(name, O_RDWR | O_CREAT, 0600)) < 0)
88	msg_fatal("%s: cannot open PRNG exchange file %s: %m", myname, name);
89    eh = (TLS_PRNG_SRC *) mymalloc(sizeof(*eh));
90    eh->fd = fd;
91    eh->name = mystrdup(name);
92    eh->timeout = 0;
93    if (msg_verbose)
94	msg_info("%s: opened PRNG exchange file %s", myname, name);
95    return (eh);
96}
97
98/* tls_prng_exch_update - update PRNG exchange file */
99
100void    tls_prng_exch_update(TLS_PRNG_SRC *eh)
101{
102    unsigned char buffer[TLS_PRNG_EXCH_SIZE];
103    ssize_t count;
104
105    /*
106     * Update the PRNG exchange file. Since other processes may have added
107     * entropy, we use a read-stir-write cycle.
108     */
109    if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
110	msg_fatal("cannot lock PRNG exchange file %s: %m", eh->name);
111    if (lseek(eh->fd, 0, SEEK_SET) < 0)
112	msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
113    if ((count = read(eh->fd, buffer, sizeof(buffer))) < 0)
114	msg_fatal("cannot read PRNG exchange file %s: %m", eh->name);
115
116    if (count > 0)
117	RAND_seed(buffer, count);
118    RAND_bytes(buffer, sizeof(buffer));
119
120    if (lseek(eh->fd, 0, SEEK_SET) < 0)
121	msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
122    if (write(eh->fd, buffer, sizeof(buffer)) != sizeof(buffer))
123	msg_fatal("cannot write PRNG exchange file %s: %m", eh->name);
124    if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
125	msg_fatal("cannot unlock PRNG exchange file %s: %m", eh->name);
126}
127
128/* tls_prng_exch_close - close PRNG exchange file */
129
130void    tls_prng_exch_close(TLS_PRNG_SRC *eh)
131{
132    const char *myname = "tls_prng_exch_close";
133
134    if (close(eh->fd) < 0)
135	msg_fatal("close PRNG exchange file %s: %m", eh->name);
136    if (msg_verbose)
137	msg_info("%s: closed PRNG exchange file %s", myname, eh->name);
138    myfree(eh->name);
139    myfree((char *) eh);
140}
141
142#endif
143