1/*++ 2/* NAME 3/* tls_prng_file 3 4/* SUMMARY 5/* seed OpenSSL PRNG from entropy file 6/* SYNOPSIS 7/* #include <tls_prng_src.h> 8/* 9/* TLS_PRNG_SRC *tls_prng_file_open(name, timeout) 10/* const char *name; 11/* int timeout; 12/* 13/* ssize_t tls_prng_file_read(fh, length) 14/* TLS_PRNG_SRC *fh; 15/* size_t length; 16/* 17/* int tls_prng_file_close(fh) 18/* TLS_PRNG_SRC *fh; 19/* DESCRIPTION 20/* tls_prng_file_open() open the specified file and returns 21/* a handle that should be used with all subsequent access. 22/* 23/* tls_prng_file_read() reads the requested number of bytes from 24/* the entropy file and updates the OpenSSL PRNG. The file is not 25/* locked for shared or exclusive access. 26/* 27/* tls_prng_file_close() closes the specified entropy file 28/* and releases memory that was allocated for the handle. 29/* 30/* Arguments: 31/* .IP name 32/* The pathname of the entropy file. 33/* .IP length 34/* The number of bytes to read from the entropy file. 35/* .IP timeout 36/* Time limit on individual I/O operations. 37/* DIAGNOSTICS 38/* tls_prng_file_open() returns a null pointer on error. 39/* 40/* tls_prng_file_read() returns -1 on error, the number 41/* of bytes received on success. 42/* 43/* tls_prng_file_close() returns -1 on error, 0 on success. 44/* 45/* In all cases the errno variable indicates the type of error. 46/* LICENSE 47/* .ad 48/* .fi 49/* The Secure Mailer license must be distributed with this software. 50/* AUTHOR(S) 51/* Wietse Venema 52/* IBM T.J. Watson Research 53/* P.O. Box 704 54/* Yorktown Heights, NY 10598, USA 55/*--*/ 56 57/* System library. */ 58 59#include <sys_defs.h> 60#include <fcntl.h> 61#include <unistd.h> 62#include <limits.h> 63#include <errno.h> 64 65/* OpenSSL library. */ 66 67#ifdef USE_TLS 68#include <openssl/rand.h> /* For the PRNG */ 69 70/* Utility library. */ 71 72#include <msg.h> 73#include <mymalloc.h> 74#include <connect.h> 75#include <iostuff.h> 76 77/* TLS library. */ 78 79#include <tls_prng.h> 80 81/* tls_prng_file_open - open entropy file */ 82 83TLS_PRNG_SRC *tls_prng_file_open(const char *name, int timeout) 84{ 85 const char *myname = "tls_prng_file_open"; 86 TLS_PRNG_SRC *fh; 87 int fd; 88 89 if ((fd = open(name, O_RDONLY, 0)) < 0) { 90 if (msg_verbose) 91 msg_info("%s: cannot open entropy file %s: %m", myname, name); 92 return (0); 93 } else { 94 fh = (TLS_PRNG_SRC *) mymalloc(sizeof(*fh)); 95 fh->fd = fd; 96 fh->name = mystrdup(name); 97 fh->timeout = timeout; 98 if (msg_verbose) 99 msg_info("%s: opened entropy file %s", myname, name); 100 return (fh); 101 } 102} 103 104/* tls_prng_file_read - update internal PRNG from entropy file */ 105 106ssize_t tls_prng_file_read(TLS_PRNG_SRC *fh, size_t len) 107{ 108 const char *myname = "tls_prng_file_read"; 109 char buffer[8192]; 110 ssize_t to_read; 111 ssize_t count; 112 113 if (msg_verbose) 114 msg_info("%s: seed internal pool from file %s", myname, fh->name); 115 116 if (lseek(fh->fd, 0, SEEK_SET) < 0) { 117 if (msg_verbose) 118 msg_info("cannot seek entropy file %s: %m", fh->name); 119 return (-1); 120 } 121 errno = 0; 122 for (to_read = len; to_read > 0; to_read -= count) { 123 if ((count = timed_read(fh->fd, buffer, to_read > sizeof(buffer) ? 124 sizeof(buffer) : to_read, 125 fh->timeout, (void *) 0)) < 0) { 126 if (msg_verbose) 127 msg_info("cannot read entropy file %s: %m", fh->name); 128 return (-1); 129 } 130 if (count == 0) 131 break; 132 RAND_seed(buffer, count); 133 } 134 if (msg_verbose) 135 msg_info("read %ld bytes from entropy file %s: %m", 136 (long) (len - to_read), fh->name); 137 return (len - to_read); 138} 139 140/* tls_prng_file_close - close entropy file */ 141 142int tls_prng_file_close(TLS_PRNG_SRC *fh) 143{ 144 const char *myname = "tls_prng_file_close"; 145 int err; 146 147 if (msg_verbose) 148 msg_info("%s: close entropy file %s", myname, fh->name); 149 err = close(fh->fd); 150 myfree(fh->name); 151 myfree((char *) fh); 152 return (err); 153} 154 155#endif 156