aboutsummaryrefslogtreecommitdiff
path: root/openssl/crypto/rand
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/crypto/rand')
-rw-r--r--openssl/crypto/rand/Makefile71
-rw-r--r--openssl/crypto/rand/md_rand.c46
-rw-r--r--openssl/crypto/rand/rand.h29
-rw-r--r--openssl/crypto/rand/rand_egd.c2
-rw-r--r--openssl/crypto/rand/rand_eng.c152
-rw-r--r--openssl/crypto/rand/rand_err.c20
-rw-r--r--openssl/crypto/rand/rand_lcl.h11
-rw-r--r--openssl/crypto/rand/rand_lib.c71
-rw-r--r--openssl/crypto/rand/rand_os2.c6
-rw-r--r--openssl/crypto/rand/rand_unix.c71
-rw-r--r--openssl/crypto/rand/rand_win.c71
-rw-r--r--openssl/crypto/rand/randfile.c33
12 files changed, 209 insertions, 374 deletions
diff --git a/openssl/crypto/rand/Makefile b/openssl/crypto/rand/Makefile
index 30794305c..27694aa66 100644
--- a/openssl/crypto/rand/Makefile
+++ b/openssl/crypto/rand/Makefile
@@ -17,9 +17,9 @@ TEST= randtest.c
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC=md_rand.c randfile.c rand_lib.c rand_eng.c rand_err.c rand_egd.c \
+LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
rand_win.c rand_unix.c rand_os2.c rand_nw.c
-LIBOBJ=md_rand.o randfile.o rand_lib.o rand_eng.o rand_err.o rand_egd.o \
+LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
rand_win.o rand_unix.o rand_os2.o rand_nw.o
SRC= $(LIBSRC)
@@ -35,7 +35,7 @@ top:
all: lib
lib: $(LIBOBJ)
- $(ARX) $(LIB) $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
$(RANLIB) $(LIB) || echo Never mind.
@touch lib
@@ -79,34 +79,17 @@ clean:
md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-md_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-md_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-md_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-md_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-md_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-md_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-md_rand.o: ../../include/openssl/symhacks.h md_rand.c rand_lcl.h
+md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+md_rand.o: md_rand.c rand_lcl.h
rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/e_os2.h
rand_egd.o: ../../include/openssl/opensslconf.h
rand_egd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
rand_egd.o: rand_egd.c
-rand_eng.o: ../../e_os.h ../../include/openssl/asn1.h
-rand_eng.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-rand_eng.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-rand_eng.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
-rand_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-rand_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-rand_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_eng.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
-rand_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rand_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rand_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rand_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-rand_eng.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rand_eng.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rand_eng.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-rand_eng.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rand_eng.o: ../cryptlib.h rand_eng.c rand_lcl.h
rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
@@ -116,39 +99,34 @@ rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rand_err.o: rand_err.c
rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-rand_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rand_lib.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rand_lib.o: ../cryptlib.h rand_lcl.h rand_lib.c
+rand_lib.o: ../cryptlib.h rand_lib.c
rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_nw.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_nw.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rand_nw.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rand_nw.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rand_nw.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rand_nw.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rand_nw.o: ../cryptlib.h rand_lcl.h rand_nw.c
+rand_nw.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_nw.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_nw.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_nw.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_nw.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_nw.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_nw.c
rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_os2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_os2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rand_os2.o: ../../include/openssl/opensslconf.h
+rand_os2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_os2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -158,8 +136,8 @@ rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_unix.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_unix.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rand_unix.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_unix.o: ../../include/openssl/objects.h
rand_unix.o: ../../include/openssl/opensslconf.h
rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
@@ -170,9 +148,8 @@ rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_win.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_win.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rand_win.o: ../../include/openssl/opensslconf.h
+rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/openssl/crypto/rand/md_rand.c b/openssl/crypto/rand/md_rand.c
index 0f8dd3e00..88088ce73 100644
--- a/openssl/crypto/rand/md_rand.c
+++ b/openssl/crypto/rand/md_rand.c
@@ -126,10 +126,6 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
#ifdef BN_DEBUG
# define PREDICT
@@ -149,7 +145,7 @@ static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
* holds CRYPTO_LOCK_RAND
* (to prevent double locking) */
/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
-static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
+static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
#ifdef PREDICT
@@ -217,8 +213,10 @@ static void ssleay_rand_add(const void *buf, int num, double add)
/* check if we already have the lock */
if (crypto_lock_rand)
{
+ CRYPTO_THREADID cur;
+ CRYPTO_THREADID_current(&cur);
CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
- do_not_lock = (locking_thread == CRYPTO_thread_id());
+ do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
}
else
@@ -274,8 +272,16 @@ static void ssleay_rand_add(const void *buf, int num, double add)
}
else
MD_Update(&m,&(state[st_idx]),j);
-
+
+ /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
MD_Update(&m,buf,j);
+ /* We know that line may cause programs such as
+ purify and valgrind to complain about use of
+ uninitialized data. The problem is not, it's
+ with the caller. Removing that line will make
+ sure you get really bad randomness and thereby
+ other problems such as very insecure keys. */
+
MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
MD_Final(&m,local_md);
md_c[1]++;
@@ -336,14 +342,6 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
#endif
int do_stir_pool = 0;
-#ifdef OPENSSL_FIPS
- if(FIPS_mode())
- {
- FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD);
- return 0;
- }
-#endif
-
#ifdef PREDICT
if (rand_predictable)
{
@@ -384,7 +382,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
- locking_thread = CRYPTO_thread_id();
+ CRYPTO_THREADID_current(&locking_threadid);
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
@@ -476,9 +474,15 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
#endif
MD_Update(&m,local_md,MD_DIGEST_LENGTH);
MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
-#ifndef PURIFY
- MD_Update(&m,buf,j); /* purify complains */
+
+#ifndef PURIFY /* purify complains */
+ /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
+ MD_Update(&m,buf,j);
+ /* We know that line may cause programs such as
+ purify and valgrind to complain about use of
+ uninitialized data. */
#endif
+
k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
if (k > 0)
{
@@ -539,15 +543,17 @@ static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
static int ssleay_rand_status(void)
{
+ CRYPTO_THREADID cur;
int ret;
int do_not_lock;
+ CRYPTO_THREADID_current(&cur);
/* check if we already have the lock
* (could happen if a RAND_poll() implementation calls RAND_status()) */
if (crypto_lock_rand)
{
CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
- do_not_lock = (locking_thread == CRYPTO_thread_id());
+ do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
}
else
@@ -559,7 +565,7 @@ static int ssleay_rand_status(void)
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
- locking_thread = CRYPTO_thread_id();
+ CRYPTO_THREADID_cpy(&locking_threadid, &cur);
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
}
diff --git a/openssl/crypto/rand/rand.h b/openssl/crypto/rand/rand.h
index ea89153cb..ac6c02176 100644
--- a/openssl/crypto/rand/rand.h
+++ b/openssl/crypto/rand/rand.h
@@ -72,7 +72,7 @@ extern "C" {
#endif
#if defined(OPENSSL_FIPS)
-#define FIPS_RAND_SIZE_T int
+#define FIPS_RAND_SIZE_T size_t
#endif
/* Already defined in ossl_typ.h */
@@ -111,15 +111,6 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
int RAND_egd(const char *path);
int RAND_egd_bytes(const char *path,int bytes);
int RAND_poll(void);
-#ifndef OPENSSL_NO_ENGINE
-#ifdef OPENSSL_FIPS
-void int_RAND_init_engine_callbacks(void);
-void int_RAND_set_callbacks(
- int (*set_rand_func)(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth),
- const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth));
-#endif
-#endif
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
@@ -137,29 +128,11 @@ void ERR_load_RAND_strings(void);
/* Error codes for the RAND functions. */
/* Function codes. */
-#define RAND_F_ENG_RAND_GET_RAND_METHOD 108
-#define RAND_F_FIPS_RAND 103
-#define RAND_F_FIPS_RAND_BYTES 102
-#define RAND_F_FIPS_RAND_GET_RAND_METHOD 109
-#define RAND_F_FIPS_RAND_SET_DT 106
-#define RAND_F_FIPS_SET_DT 104
-#define RAND_F_FIPS_SET_PRNG_SEED 107
-#define RAND_F_FIPS_SET_TEST_MODE 105
#define RAND_F_RAND_GET_RAND_METHOD 101
#define RAND_F_SSLEAY_RAND_BYTES 100
/* Reason codes. */
-#define RAND_R_NON_FIPS_METHOD 105
-#define RAND_R_NOT_IN_TEST_MODE 106
-#define RAND_R_NO_KEY_SET 107
-#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101
-#define RAND_R_PRNG_ERROR 108
-#define RAND_R_PRNG_KEYED 109
-#define RAND_R_PRNG_NOT_REKEYED 102
-#define RAND_R_PRNG_NOT_RESEEDED 103
#define RAND_R_PRNG_NOT_SEEDED 100
-#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110
-#define RAND_R_PRNG_STUCK 104
#ifdef __cplusplus
}
diff --git a/openssl/crypto/rand/rand_egd.c b/openssl/crypto/rand/rand_egd.c
index 50bce6cab..d53b916eb 100644
--- a/openssl/crypto/rand/rand_egd.c
+++ b/openssl/crypto/rand/rand_egd.c
@@ -95,7 +95,7 @@
* RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
*/
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS)
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
{
return(-1);
diff --git a/openssl/crypto/rand/rand_eng.c b/openssl/crypto/rand/rand_eng.c
deleted file mode 100644
index 1669cef43..000000000
--- a/openssl/crypto/rand/rand_eng.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* crypto/rand/rand_lib.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include <time.h>
-#include "cryptlib.h"
-#include "rand_lcl.h"
-#include <openssl/rand.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#include <openssl/fips_rand.h>
-#endif
-
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-
-#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE)
-
-/* non-NULL if default_RAND_meth is ENGINE-provided */
-static ENGINE *funct_ref =NULL;
-
-int eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth)
- {
- if(funct_ref)
- {
- ENGINE_finish(funct_ref);
- funct_ref = NULL;
- }
- *pmeth = meth;
- return 1;
- }
-
-const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth)
- {
- if (!*pmeth)
- {
- ENGINE *e = ENGINE_get_default_RAND();
- if(e)
- {
- *pmeth = ENGINE_get_RAND(e);
- if(!*pmeth)
- {
- ENGINE_finish(e);
- e = NULL;
- }
- }
- if(e)
- funct_ref = e;
- else
- if(FIPS_mode())
- *pmeth=FIPS_rand_method();
- else
- *pmeth = RAND_SSLeay();
- }
-
- if(FIPS_mode()
- && *pmeth != FIPS_rand_check())
- {
- RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
- return 0;
- }
-
- return *pmeth;
- }
-
-int RAND_set_rand_engine(ENGINE *engine)
- {
- const RAND_METHOD *tmp_meth = NULL;
- if(engine)
- {
- if(!ENGINE_init(engine))
- return 0;
- tmp_meth = ENGINE_get_RAND(engine);
- if(!tmp_meth)
- {
- ENGINE_finish(engine);
- return 0;
- }
- }
- /* This function releases any prior ENGINE so call it first */
- RAND_set_rand_method(tmp_meth);
- funct_ref = engine;
- return 1;
- }
-
-void int_RAND_init_engine_callbacks(void)
- {
- static int done = 0;
- if (done)
- return;
- int_RAND_set_callbacks(eng_RAND_set_rand_method,
- eng_RAND_get_rand_method);
- done = 1;
- }
-
-#endif
diff --git a/openssl/crypto/rand/rand_err.c b/openssl/crypto/rand/rand_err.c
index 829fb44d7..03cda4dd9 100644
--- a/openssl/crypto/rand/rand_err.c
+++ b/openssl/crypto/rand/rand_err.c
@@ -1,6 +1,6 @@
/* crypto/rand/rand_err.c */
/* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -70,14 +70,6 @@
static ERR_STRING_DATA RAND_str_functs[]=
{
-{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"},
-{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"},
-{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"},
-{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD), "FIPS_RAND_GET_RAND_METHOD"},
-{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"},
-{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"},
-{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"},
-{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"},
{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
{0,NULL}
@@ -85,17 +77,7 @@ static ERR_STRING_DATA RAND_str_functs[]=
static ERR_STRING_DATA RAND_str_reasons[]=
{
-{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"},
-{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"},
-{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"},
-{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"},
-{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"},
-{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"},
-{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"},
-{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"},
{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
-{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"},
-{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"},
{0,NULL}
};
diff --git a/openssl/crypto/rand/rand_lcl.h b/openssl/crypto/rand/rand_lcl.h
index 18cc9b1e4..618a8ec89 100644
--- a/openssl/crypto/rand/rand_lcl.h
+++ b/openssl/crypto/rand/rand_lcl.h
@@ -154,16 +154,5 @@
#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
#endif
-#ifndef OPENSSL_NO_ENGINE
-void int_RAND_set_callbacks(
- int (*set_rand_func)(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth),
- const RAND_METHOD *(*get_rand_func)
- (const RAND_METHOD **pmeth));
-int eng_RAND_set_rand_method(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth);
-const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth);
-#endif
-
#endif
diff --git a/openssl/crypto/rand/rand_lib.c b/openssl/crypto/rand/rand_lib.c
index da6b4e0e8..513e33898 100644
--- a/openssl/crypto/rand/rand_lib.c
+++ b/openssl/crypto/rand/rand_lib.c
@@ -60,82 +60,15 @@
#include <time.h>
#include "cryptlib.h"
#include <openssl/rand.h>
-#include "rand_lcl.h"
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#include <openssl/fips_rand.h>
-#endif
-
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
-static const RAND_METHOD *default_RAND_meth = NULL;
-
-#ifdef OPENSSL_FIPS
-
-static int fips_RAND_set_rand_method(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth)
- {
- *pmeth = meth;
- return 1;
- }
-
-static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth)
- {
- if (!*pmeth)
- {
- if(FIPS_mode())
- *pmeth=FIPS_rand_method();
- else
- *pmeth = RAND_SSLeay();
- }
-
- if(FIPS_mode()
- && *pmeth != FIPS_rand_check())
- {
- RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
- return 0;
- }
-
- return *pmeth;
- }
-
-static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth)
- = fips_RAND_set_rand_method;
-static const RAND_METHOD *(*RAND_get_rand_method_func)
- (const RAND_METHOD **pmeth)
- = fips_RAND_get_rand_method;
-
-#ifndef OPENSSL_NO_ENGINE
-void int_RAND_set_callbacks(
- int (*set_rand_func)(const RAND_METHOD *meth,
- const RAND_METHOD **pmeth),
- const RAND_METHOD *(*get_rand_func)
- (const RAND_METHOD **pmeth))
- {
- RAND_set_rand_method_func = set_rand_func;
- RAND_get_rand_method_func = get_rand_func;
- }
-#endif
-
-int RAND_set_rand_method(const RAND_METHOD *meth)
- {
- return RAND_set_rand_method_func(meth, &default_RAND_meth);
- }
-
-const RAND_METHOD *RAND_get_rand_method(void)
- {
- return RAND_get_rand_method_func(&default_RAND_meth);
- }
-
-#else
-
#ifndef OPENSSL_NO_ENGINE
/* non-NULL if default_RAND_meth is ENGINE-provided */
static ENGINE *funct_ref =NULL;
#endif
+static const RAND_METHOD *default_RAND_meth = NULL;
int RAND_set_rand_method(const RAND_METHOD *meth)
{
@@ -196,8 +129,6 @@ int RAND_set_rand_engine(ENGINE *engine)
}
#endif
-#endif
-
void RAND_cleanup(void)
{
const RAND_METHOD *meth = RAND_get_rand_method();
diff --git a/openssl/crypto/rand/rand_os2.c b/openssl/crypto/rand/rand_os2.c
index c3e36d4e5..fc1e78b17 100644
--- a/openssl/crypto/rand/rand_os2.c
+++ b/openssl/crypto/rand/rand_os2.c
@@ -78,8 +78,10 @@ typedef struct _CPUUTIL {
ULONG ulIntrHigh; /* High 32 bits of interrupt time */
} CPUUTIL;
+#ifndef __KLIBC__
APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
+#endif
HMODULE hDoscalls = 0;
int RAND_poll(void)
@@ -91,6 +93,7 @@ int RAND_poll(void)
if (hDoscalls == 0) {
ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
+#ifndef __KLIBC__
if (rc == 0) {
rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
@@ -102,6 +105,7 @@ int RAND_poll(void)
if (rc)
DosQuerySysState = NULL;
}
+#endif
}
/* Sample the hi-res timer, runs at around 1.1 MHz */
@@ -122,7 +126,9 @@ int RAND_poll(void)
RAND_add(&util, sizeof(util), 10);
}
else {
+#ifndef __KLIBC__
DosPerfSysCall = NULL;
+#endif
}
}
diff --git a/openssl/crypto/rand/rand_unix.c b/openssl/crypto/rand/rand_unix.c
index 71b98ec21..e9ead3a52 100644
--- a/openssl/crypto/rand/rand_unix.c
+++ b/openssl/crypto/rand/rand_unix.c
@@ -133,7 +133,50 @@
# define FD_SETSIZE (8*sizeof(fd_set))
#endif
-#ifdef __OpenBSD__
+#ifdef __VOS__
+int RAND_poll(void)
+{
+ unsigned char buf[ENTROPY_NEEDED];
+ pid_t curr_pid;
+ uid_t curr_uid;
+ static int first=1;
+ int i;
+ long rnd = 0;
+ struct timespec ts;
+ unsigned seed;
+
+/* The VOS random() function starts from a static seed so its
+ initial value is predictable. If random() returns the
+ initial value, reseed it with dynamic data. The VOS
+ real-time clock has a granularity of 1 nsec so it should be
+ reasonably difficult to predict its exact value. Do not
+ gratuitously reseed the PRNG because other code in this
+ process or thread may be using it. */
+
+ if (first) {
+ first = 0;
+ rnd = random ();
+ if (rnd == 1804289383) {
+ clock_gettime (CLOCK_REALTIME, &ts);
+ curr_pid = getpid();
+ curr_uid = getuid();
+ seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
+ srandom (seed);
+ }
+ }
+
+ for (i = 0; i < sizeof(buf); i++) {
+ if (i % 4 == 0)
+ rnd = random();
+ buf[i] = rnd;
+ rnd >>= 8;
+ }
+ RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+ memset(buf, 0, sizeof(buf));
+
+ return 1;
+}
+#elif defined __OpenBSD__
int RAND_poll(void)
{
u_int32_t rnd = 0, i;
@@ -163,7 +206,7 @@ int RAND_poll(void)
static const char *randomfiles[] = { DEVRANDOM };
struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
int fd;
- size_t i;
+ unsigned int i;
#endif
#ifdef DEVRANDOM_EGD
static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -176,7 +219,8 @@ int RAND_poll(void)
* have this. Use /dev/urandom if you can as /dev/random may block
* if it runs out of random entries. */
- for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
+ for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
+ (n < ENTROPY_NEEDED); i++)
{
if ((fd = open(randomfiles[i], O_RDONLY
#ifdef O_NONBLOCK
@@ -193,7 +237,7 @@ int RAND_poll(void)
{
int usec = 10*1000; /* spend 10ms on each file */
int r;
- size_t j;
+ unsigned int j;
struct stat *st=&randomstats[i];
/* Avoid using same input... Used to be O_NOFOLLOW
@@ -211,7 +255,12 @@ int RAND_poll(void)
{
int try_read = 0;
-#if defined(OPENSSL_SYS_LINUX)
+#if defined(OPENSSL_SYS_BEOS_R5)
+ /* select() is broken in BeOS R5, so we simply
+ * try to read something and snooze if we couldn't */
+ try_read = 1;
+
+#elif defined(OPENSSL_SYS_LINUX)
/* use poll() */
struct pollfd pset;
@@ -258,6 +307,10 @@ int RAND_poll(void)
r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
if (r > 0)
n += r;
+#if defined(OPENSSL_SYS_BEOS_R5)
+ if (r == 0)
+ snooze(t.tv_usec);
+#endif
}
else
r = -1;
@@ -311,6 +364,14 @@ int RAND_poll(void)
l=time(NULL);
RAND_add(&l,sizeof(l),0.0);
+#if defined(OPENSSL_SYS_BEOS)
+ {
+ system_info sysInfo;
+ get_system_info(&sysInfo);
+ RAND_add(&sysInfo,sizeof(sysInfo),0);
+ }
+#endif
+
#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
return 1;
#else
diff --git a/openssl/crypto/rand/rand_win.c b/openssl/crypto/rand/rand_win.c
index 00dbe4232..5d134e186 100644
--- a/openssl/crypto/rand/rand_win.c
+++ b/openssl/crypto/rand/rand_win.c
@@ -463,7 +463,7 @@ int RAND_poll(void)
PROCESSENTRY32 p;
THREADENTRY32 t;
MODULEENTRY32 m;
- DWORD stoptime = 0;
+ DWORD starttime = 0;
snap = (CREATETOOLHELP32SNAPSHOT)
GetProcAddress(kernel, "CreateToolhelp32Snapshot");
@@ -494,12 +494,29 @@ int RAND_poll(void)
* each entry. Consider each field a source of 1 byte
* of entropy.
*/
+ ZeroMemory(&hlist, sizeof(HEAPLIST32));
hlist.dwSize = sizeof(HEAPLIST32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
+#ifdef _MSC_VER
if (heaplist_first(handle, &hlist))
+ {
+ /*
+ following discussion on dev ML, exception on WinCE (or other Win
+ platform) is theoretically of unknown origin; prevent infinite
+ loop here when this theoretical case occurs; otherwise cope with
+ the expected (MSDN documented) exception-throwing behaviour of
+ Heap32Next() on WinCE.
+
+ based on patch in original message by Tanguy Fautré (2009/03/02)
+ Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
+ */
+ int ex_cnt_limit = 42;
do
{
RAND_add(&hlist, hlist.dwSize, 3);
+ __try
+ {
+ ZeroMemory(&hentry, sizeof(HEAPENTRY32));
hentry.dwSize = sizeof(HEAPENTRY32);
if (heap_first(&hentry,
hlist.th32ProcessID,
@@ -510,10 +527,42 @@ int RAND_poll(void)
RAND_add(&hentry,
hentry.dwSize, 5);
while (heap_next(&hentry)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
&& --entrycnt > 0);
}
- } while (heaplist_next(handle,
- &hlist) && GetTickCount() < stoptime);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* ignore access violations when walking the heap list */
+ ex_cnt_limit--;
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
+ && ex_cnt_limit > 0);
+ }
+
+#else
+ if (heaplist_first(handle, &hlist))
+ {
+ do
+ {
+ RAND_add(&hlist, hlist.dwSize, 3);
+ hentry.dwSize = sizeof(HEAPENTRY32);
+ if (heap_first(&hentry,
+ hlist.th32ProcessID,
+ hlist.th32HeapID))
+ {
+ int entrycnt = 80;
+ do
+ RAND_add(&hentry,
+ hentry.dwSize, 5);
+ while (heap_next(&hentry)
+ && --entrycnt > 0);
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
+ }
+#endif
/* process walking */
/* PROCESSENTRY32 contains 9 fields that will change
@@ -522,11 +571,11 @@ int RAND_poll(void)
*/
p.dwSize = sizeof(PROCESSENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (process_first(handle, &p))
do
RAND_add(&p, p.dwSize, 9);
- while (process_next(handle, &p) && GetTickCount() < stoptime);
+ while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* thread walking */
/* THREADENTRY32 contains 6 fields that will change
@@ -534,11 +583,11 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
t.dwSize = sizeof(THREADENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (thread_first(handle, &t))
do
RAND_add(&t, t.dwSize, 6);
- while (thread_next(handle, &t) && GetTickCount() < stoptime);
+ while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* module walking */
/* MODULEENTRY32 contains 9 fields that will change
@@ -546,12 +595,12 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
m.dwSize = sizeof(MODULEENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (module_first(handle, &m))
do
RAND_add(&m, m.dwSize, 9);
while (module_next(handle, &m)
- && (GetTickCount() < stoptime));
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
if (close_snap)
close_snap(handle);
else
@@ -701,7 +750,7 @@ static void readscreen(void)
int y; /* y-coordinate of screen lines to grab */
int n = 16; /* number of screen lines to grab at a time */
- if (GetVersion() >= 0x80000000 || !OPENSSL_isservice())
+ if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
return;
/* Create a screen DC and a memory DC compatible to screen DC */
diff --git a/openssl/crypto/rand/randfile.c b/openssl/crypto/rand/randfile.c
index d108353bb..4ed40b7b7 100644
--- a/openssl/crypto/rand/randfile.c
+++ b/openssl/crypto/rand/randfile.c
@@ -75,9 +75,7 @@
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
-#ifdef MAC_OS_pre_X
-# include <stat.h>
-#else
+#ifndef OPENSSL_NO_POSIX_IO
# include <sys/stat.h>
#endif
@@ -111,14 +109,26 @@ int RAND_load_file(const char *file, long bytes)
* if bytes == -1, read complete file. */
MS_STATIC unsigned char buf[BUFSIZE];
+#ifndef OPENSSL_NO_POSIX_IO
struct stat sb;
+#endif
int i,ret=0,n;
FILE *in;
if (file == NULL) return(0);
+#ifndef OPENSSL_NO_POSIX_IO
+#ifdef PURIFY
+ /* struct stat can have padding and unused fields that may not be
+ * initialized in the call to stat(). We need to clear the entire
+ * structure before calling RAND_add() to avoid complaints from
+ * applications such as Valgrind.
+ */
+ memset(&sb, 0, sizeof(sb));
+#endif
if (stat(file,&sb) < 0) return(0);
RAND_add(&sb,sizeof(sb),0.0);
+#endif
if (bytes == 0) return(ret);
#ifdef OPENSSL_SYS_VMS
@@ -127,7 +137,7 @@ int RAND_load_file(const char *file, long bytes)
in=fopen(file,"rb");
#endif
if (in == NULL) goto err;
-#if defined(S_IFBLK) && defined(S_IFCHR)
+#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/* this file is a device. we don't want read an infinite number
* of bytes from a random device, nor do we want to use buffered
@@ -170,12 +180,13 @@ int RAND_write_file(const char *file)
int i,ret=0,rand_err=0;
FILE *out = NULL;
int n;
+#ifndef OPENSSL_NO_POSIX_IO
struct stat sb;
i=stat(file,&sb);
if (i != -1) {
-#if defined(S_IFBLK) && defined(S_IFCHR)
- if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
+#if defined(S_ISBLK) && defined(S_ISCHR)
+ if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
/* this file is a device. we don't write back to it.
* we "succeed" on the assumption this is some sort
* of random device. Otherwise attempting to write to
@@ -185,14 +196,16 @@ int RAND_write_file(const char *file)
}
#endif
}
+#endif
-#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS)
+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
{
- /* For some reason Win32 can't write to files created this way */
-
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
/* chmod(..., 0600) is too late to protect the file,
* permissions should be restrictive from the start */
- int fd = open(file, O_CREAT, 0600);
+ int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600);
if (fd != -1)
out = fdopen(fd, "wb");
}