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