diff options
| author | miod <> | 2014-04-15 16:52:50 +0000 |
|---|---|---|
| committer | miod <> | 2014-04-15 16:52:50 +0000 |
| commit | 7a19a50981d49325d35ae058d54f915cbfa1a027 (patch) | |
| tree | cd099da9298b8ab84a5dbbead9a6560737057c97 /src/lib/libcrypto/rand/randfile.c | |
| parent | 2d3ffc156e48e292feaa28edc341e694571d2b00 (diff) | |
| download | openbsd-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.c | 152 |
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 */ | ||
| 98 | static 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 | ||
| 108 | int RAND_load_file(const char *file, long bytes) | 82 | int 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); | ||
| 177 | err: | ||
| 178 | return(ret); | ||
| 179 | } | 85 | } |
| 180 | 86 | ||
| 181 | int RAND_write_file(const char *file) | 87 | int 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: | |||
| 273 | const char *RAND_file_name(char *buf, size_t size) | 143 | const 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 | } |
