7 /* maintain PRNG exchange file
9 /* #include <tls_prng_src.h>
11 /* TLS_PRNG_SRC *tls_prng_exch_open(name, timeout)
15 /* void tls_prng_exch_update(fh, length)
19 /* void tls_prng_exch_close(fh)
22 /* tls_prng_exch_open() opens the specified PRNG exchange file
23 /* and returns a handle that should be used with all subsequent
26 /* tls_prng_exch_update() reads the requested number of bytes
27 /* from the PRNG exchange file, updates the OpenSSL PRNG, and
28 /* writes the requested number of bytes to the exchange file.
29 /* The file is locked for exclusive access.
31 /* tls_prng_exch_close() closes the specified PRNG exchange
32 /* file and releases memory that was allocated for the handle.
36 /* The name of the PRNG exchange file.
38 /* The number of bytes to read from/write to the entropy file.
40 /* Time limit on individual I/O operations.
42 /* All errors are fatal.
46 /* The Secure Mailer license must be distributed with this software.
49 /* IBM T.J. Watson Research
51 /* Yorktown Heights, NY 10598, USA
61 /* OpenSSL library. */
64 #include <openssl/rand.h> /* For the PRNG */
66 /* Utility library. */
77 /* Application specific. */
79 #define TLS_PRNG_EXCH_SIZE 1024 /* XXX Why not configurable? */
81 /* tls_prng_exch_open - open PRNG exchange file */
83 TLS_PRNG_SRC
*tls_prng_exch_open(const char *name
)
85 const char *myname
= "tls_prng_exch_open";
89 if ((fd
= open(name
, O_RDWR
| O_CREAT
, 0600)) < 0)
90 msg_fatal("%s: cannot open PRNG exchange file %s: %m", myname
, name
);
91 eh
= (TLS_PRNG_SRC
*) mymalloc(sizeof(*eh
));
93 eh
->name
= mystrdup(name
);
96 msg_info("%s: opened PRNG exchange file %s", myname
, name
);
100 /* tls_prng_exch_update - update PRNG exchange file */
102 void tls_prng_exch_update(TLS_PRNG_SRC
*eh
)
104 unsigned char buffer
[TLS_PRNG_EXCH_SIZE
];
108 * Update the PRNG exchange file. Since other processes may have added
109 * entropy, we use a read-stir-write cycle.
111 if (myflock(eh
->fd
, INTERNAL_LOCK
, MYFLOCK_OP_EXCLUSIVE
) != 0)
112 msg_fatal("cannot lock PRNG exchange file %s: %m", eh
->name
);
113 if (lseek(eh
->fd
, 0, SEEK_SET
) < 0)
114 msg_fatal("cannot seek PRNG exchange file %s: %m", eh
->name
);
115 if ((count
= read(eh
->fd
, buffer
, sizeof(buffer
))) < 0)
116 msg_fatal("cannot read PRNG exchange file %s: %m", eh
->name
);
119 RAND_seed(buffer
, count
);
120 RAND_bytes(buffer
, sizeof(buffer
));
122 if (lseek(eh
->fd
, 0, SEEK_SET
) < 0)
123 msg_fatal("cannot seek PRNG exchange file %s: %m", eh
->name
);
124 if (write(eh
->fd
, buffer
, sizeof(buffer
)) != sizeof(buffer
))
125 msg_fatal("cannot write PRNG exchange file %s: %m", eh
->name
);
126 if (myflock(eh
->fd
, INTERNAL_LOCK
, MYFLOCK_OP_NONE
) != 0)
127 msg_fatal("cannot unlock PRNG exchange file %s: %m", eh
->name
);
130 /* tls_prng_exch_close - close PRNG exchange file */
132 void tls_prng_exch_close(TLS_PRNG_SRC
*eh
)
134 const char *myname
= "tls_prng_exch_close";
136 if (close(eh
->fd
) < 0)
137 msg_fatal("close PRNG exchange file %s: %m", eh
->name
);
139 msg_info("%s: closed PRNG exchange file %s", myname
, eh
->name
);