Home | History | Annotate | Line # | Download | only in tls
      1 /*	$NetBSD: tls_prng_file.c,v 1.3 2026/05/09 18:49:21 christos 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 	/* 202604 Claude: remove '%m' from non-error logging. */
    138 	msg_info("read %ld bytes from entropy file %s",
    139 		 (long) (len - to_read), fh->name);
    140     return (len - to_read);
    141 }
    142 
    143 /* tls_prng_file_close - close entropy file */
    144 
    145 int     tls_prng_file_close(TLS_PRNG_SRC *fh)
    146 {
    147     const char *myname = "tls_prng_file_close";
    148     int     err;
    149 
    150     if (msg_verbose)
    151 	msg_info("%s: close entropy file %s", myname, fh->name);
    152     err = close(fh->fd);
    153     myfree(fh->name);
    154     myfree((void *) fh);
    155     return (err);
    156 }
    157 
    158 #endif
    159