summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/randfile.c
diff options
context:
space:
mode:
authormiod <>2014-04-15 16:52:50 +0000
committermiod <>2014-04-15 16:52:50 +0000
commit7a19a50981d49325d35ae058d54f915cbfa1a027 (patch)
treecd099da9298b8ab84a5dbbead9a6560737057c97 /src/lib/libcrypto/rand/randfile.c
parent2d3ffc156e48e292feaa28edc341e694571d2b00 (diff)
downloadopenbsd-7a19a50981d49325d35ae058d54f915cbfa1a027.tar.gz
openbsd-7a19a50981d49325d35ae058d54f915cbfa1a027.tar.bz2
openbsd-7a19a50981d49325d35ae058d54f915cbfa1a027.zip
Replace the old OpenSSL PRNG by direct use of arc4random_buf(), keeping the
existing RAND interfaces unchanged. All interfaces allowing external feed or seed of the RNG (either from a file or a local entropy gathering daemon) are kept for ABI compatibility, but are no longer do anything. While the OpenSSL PRNG was required 15+ years ago when many systems lacked proper entropy collection, things have evolved and one can reasonably assume it is better to use the kernel (system global) entropy pool rather than trying to build one's own and having to compensate for thread scheduling... <RANT> Whoever thought that RAND_screen(), feeding the PRNG with the contents of the local workstation's display, under Win32, was a smart idea, ought to be banned from security programming. </RANT> ok beck@ deraadt@ tedu@
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/rand/randfile.c152
1 files changed, 5 insertions, 147 deletions
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index 10d511b8e8..2cacebcf07 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -56,11 +56,6 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59/* We need to define this to get macros like S_IFBLK and S_IFCHR */
60#if !defined(OPENSSL_SYS_VXWORKS)
61#define _XOPEN_SOURCE 500
62#endif
63
64#include <errno.h> 59#include <errno.h>
65#include <stdio.h> 60#include <stdio.h>
66#include <stdlib.h> 61#include <stdlib.h>
@@ -71,35 +66,14 @@
71#include <openssl/rand.h> 66#include <openssl/rand.h>
72#include <openssl/buffer.h> 67#include <openssl/buffer.h>
73 68
74#ifdef OPENSSL_SYS_VMS 69#include <sys/types.h>
75#include <unixio.h> 70#include <sys/stat.h>
76#endif 71#include <fcntl.h>
77#ifndef NO_SYS_TYPES_H
78# include <sys/types.h>
79#endif
80#ifndef OPENSSL_NO_POSIX_IO
81# include <sys/stat.h>
82#endif
83
84#ifdef _WIN32
85#define stat _stat
86#define chmod _chmod
87#define open _open
88#define fdopen _fdopen
89#endif
90 72
91#undef BUFSIZE 73#undef BUFSIZE
92#define BUFSIZE 1024 74#define BUFSIZE 1024
93#define RAND_DATA 1024 75#define RAND_DATA 1024
94 76
95#ifdef OPENSSL_SYS_VMS
96/* This declaration is a nasty hack to get around vms' extension to fopen
97 * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
98static FILE *(*const vms_fopen)(const char *, const char *, ...) =
99 (FILE *(*)(const char *, const char *, ...))fopen;
100#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
101#endif
102
103/* #define RFILE ".rnd" - defined in ../../e_os.h */ 77/* #define RFILE ".rnd" - defined in ../../e_os.h */
104 78
105/* Note that these functions are intended for seed files only. 79/* Note that these functions are intended for seed files only.
@@ -107,75 +81,7 @@ static FILE *(*const vms_fopen)(const char *, const char *, ...) =
107 81
108int RAND_load_file(const char *file, long bytes) 82int RAND_load_file(const char *file, long bytes)
109 { 83 {
110 /* If bytes >= 0, read up to 'bytes' bytes. 84 return(0);
111 * if bytes == -1, read complete file. */
112
113 unsigned char buf[BUFSIZE];
114#ifndef OPENSSL_NO_POSIX_IO
115 struct stat sb;
116#endif
117 int i,ret=0,n;
118 FILE *in;
119
120 if (file == NULL) return(0);
121
122#ifndef OPENSSL_NO_POSIX_IO
123#ifdef PURIFY
124 /* struct stat can have padding and unused fields that may not be
125 * initialized in the call to stat(). We need to clear the entire
126 * structure before calling RAND_add() to avoid complaints from
127 * applications such as Valgrind.
128 */
129 memset(&sb, 0, sizeof(sb));
130#endif
131 if (stat(file,&sb) < 0) return(0);
132 RAND_add(&sb,sizeof(sb),0.0);
133#endif
134 if (bytes == 0) return(ret);
135
136#ifdef OPENSSL_SYS_VMS
137 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
138#else
139 in=fopen(file,"rb");
140#endif
141 if (in == NULL) goto err;
142#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
143 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
144 /* this file is a device. we don't want read an infinite number
145 * of bytes from a random device, nor do we want to use buffered
146 * I/O because we will waste system entropy.
147 */
148 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
149#ifndef OPENSSL_NO_SETVBUF_IONBF
150 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
151#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
152 }
153#endif
154 for (;;)
155 {
156 if (bytes > 0)
157 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
158 else
159 n = BUFSIZE;
160 i=fread(buf,1,n,in);
161 if (i <= 0) break;
162#ifdef PURIFY
163 RAND_add(buf,i,(double)i);
164#else
165 /* even if n != i, use the full array */
166 RAND_add(buf,n,(double)i);
167#endif
168 ret+=i;
169 if (bytes > 0)
170 {
171 bytes-=n;
172 if (bytes <= 0) break;
173 }
174 }
175 fclose(in);
176 OPENSSL_cleanse(buf,BUFSIZE);
177err:
178 return(ret);
179 } 85 }
180 86
181int RAND_write_file(const char *file) 87int RAND_write_file(const char *file)
@@ -184,12 +90,10 @@ int RAND_write_file(const char *file)
184 int i,ret=0,rand_err=0; 90 int i,ret=0,rand_err=0;
185 FILE *out = NULL; 91 FILE *out = NULL;
186 int n; 92 int n;
187#ifndef OPENSSL_NO_POSIX_IO
188 struct stat sb; 93 struct stat sb;
189 94
190 i=stat(file,&sb); 95 i=stat(file,&sb);
191 if (i != -1) { 96 if (i != -1) {
192#if defined(S_ISBLK) && defined(S_ISCHR)
193 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { 97 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
194 /* this file is a device. we don't write back to it. 98 /* this file is a device. we don't write back to it.
195 * we "succeed" on the assumption this is some sort 99 * we "succeed" on the assumption this is some sort
@@ -198,55 +102,21 @@ int RAND_write_file(const char *file)
198 */ 102 */
199 return(1); 103 return(1);
200 } 104 }
201#endif
202 } 105 }
203#endif
204 106
205#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
206 { 107 {
207#ifndef O_BINARY
208#define O_BINARY 0
209#endif
210 /* chmod(..., 0600) is too late to protect the file, 108 /* chmod(..., 0600) is too late to protect the file,
211 * permissions should be restrictive from the start */ 109 * permissions should be restrictive from the start */
212 int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); 110 int fd = open(file, O_WRONLY|O_CREAT, 0600);
213 if (fd != -1) 111 if (fd != -1)
214 out = fdopen(fd, "wb"); 112 out = fdopen(fd, "wb");
215 } 113 }
216#endif
217
218#ifdef OPENSSL_SYS_VMS
219 /* VMS NOTE: Prior versions of this routine created a _new_
220 * version of the rand file for each call into this routine, then
221 * deleted all existing versions named ;-1, and finally renamed
222 * the current version as ';1'. Under concurrent usage, this
223 * resulted in an RMS race condition in rename() which could
224 * orphan files (see vms message help for RMS$_REENT). With the
225 * fopen() calls below, openssl/VMS now shares the top-level
226 * version of the rand file. Note that there may still be
227 * conditions where the top-level rand file is locked. If so, this
228 * code will then create a new version of the rand file. Without
229 * the delete and rename code, this can result in ascending file
230 * versions that stop at version 32767, and this routine will then
231 * return an error. The remedy for this is to recode the calling
232 * application to avoid concurrent use of the rand file, or
233 * synchronize usage at the application level. Also consider
234 * whether or not you NEED a persistent rand file in a concurrent
235 * use situation.
236 */
237 114
238 out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
239 if (out == NULL)
240 out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
241#else
242 if (out == NULL) 115 if (out == NULL)
243 out = fopen(file,"wb"); 116 out = fopen(file,"wb");
244#endif
245 if (out == NULL) goto err; 117 if (out == NULL) goto err;
246 118
247#ifndef NO_CHMOD
248 chmod(file,0600); 119 chmod(file,0600);
249#endif
250 n=RAND_DATA; 120 n=RAND_DATA;
251 for (;;) 121 for (;;)
252 { 122 {
@@ -273,9 +143,7 @@ err:
273const char *RAND_file_name(char *buf, size_t size) 143const char *RAND_file_name(char *buf, size_t size)
274 { 144 {
275 char *s=NULL; 145 char *s=NULL;
276#ifdef __OpenBSD__
277 struct stat sb; 146 struct stat sb;
278#endif
279 147
280 if (OPENSSL_issetugid() == 0) 148 if (OPENSSL_issetugid() == 0)
281 s=getenv("RANDFILE"); 149 s=getenv("RANDFILE");
@@ -288,25 +156,16 @@ const char *RAND_file_name(char *buf, size_t size)
288 { 156 {
289 if (OPENSSL_issetugid() == 0) 157 if (OPENSSL_issetugid() == 0)
290 s=getenv("HOME"); 158 s=getenv("HOME");
291#ifdef DEFAULT_HOME
292 if (s == NULL)
293 {
294 s = DEFAULT_HOME;
295 }
296#endif
297 if (s && *s && strlen(s)+strlen(RFILE)+2 < size) 159 if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
298 { 160 {
299 BUF_strlcpy(buf,s,size); 161 BUF_strlcpy(buf,s,size);
300#ifndef OPENSSL_SYS_VMS
301 BUF_strlcat(buf,"/",size); 162 BUF_strlcat(buf,"/",size);
302#endif
303 BUF_strlcat(buf,RFILE,size); 163 BUF_strlcat(buf,RFILE,size);
304 } 164 }
305 else 165 else
306 buf[0] = '\0'; /* no file name */ 166 buf[0] = '\0'; /* no file name */
307 } 167 }
308 168
309#ifdef __OpenBSD__
310 /* given that all random loads just fail if the file can't be 169 /* given that all random loads just fail if the file can't be
311 * seen on a stat, we stat the file we're returning, if it 170 * seen on a stat, we stat the file we're returning, if it
312 * fails, use /dev/arandom instead. this allows the user to 171 * fails, use /dev/arandom instead. this allows the user to
@@ -323,6 +182,5 @@ const char *RAND_file_name(char *buf, size_t size)
323 return(NULL); 182 return(NULL);
324 } 183 }
325 184
326#endif
327 return(buf); 185 return(buf);
328 } 186 }