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