summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/rand/md_rand.c
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2017-08-31 13:57:30 -0400
committerPeter Jones <pjones@redhat.com>2017-08-31 15:13:58 -0400
commit1d39ada8cb336d9e7c156be7526b674851fbdd40 (patch)
treedc497e33b1d4830bf58d79dedc3026087f31f044 /Cryptlib/OpenSSL/crypto/rand/md_rand.c
parenteae64276ffe0361d2b4087c48390d12f157f65f0 (diff)
downloadefi-boot-shim-1d39ada8cb336d9e7c156be7526b674851fbdd40.tar.gz
efi-boot-shim-1d39ada8cb336d9e7c156be7526b674851fbdd40.zip
Revert lots of Cryptlib updates.
OpenSSL changes quite a bit of the key validation, and most of the keys I can find in the wild aren't marked as trusted by the new checker. Intel noticed this too: https://github.com/vathpela/edk2/commit/f536d7c3ed but instead of fixing the compatibility error, they switched their test data to match the bug. So that's pretty broken. For now, I'm reverting OpenSSL 1.1.0e, because we need those certs in the wild to work. This reverts commit 513cbe2aea689bf968f171f894f3d4cdb43524d5. This reverts commit e9cc33d6f2b7f35c6f5e349fd83fb9ae0bc66226. This reverts commit 80d49f758ead0180bfe6161931838e0578248303. This reverts commit 9bc647e2b23bcfd69a0077c0717fbc454c919a57. This reverts commit ae75df6232ad30f3e8736e9449692d58a7439260. This reverts commit e883479f35644d17db7efed710657c8543cfcb68. This reverts commit 97469449fda5ba933a64280917e776487301a127. This reverts commit e39692647f78e13d757ddbfdd36f440d5f526050. This reverts commit 0f3dfc01e2d5e7df882c963dd8dc4a0dfbfc96ad. This reverts commit 4da6ac819510c7cc4ba21d7a735d69b45daa5873. This reverts commit d064bd7eef201f26cb926450a76260b5187ac689. This reverts commit 9bc86cfd6f9387f0da9d5c0102b6aa5627e91c91. This reverts commit ab9a05a10f16b33f7ee1e9da360c7801eebdb9d2. Signed-off-by: Peter Jones <pjones@redhat.com>
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/rand/md_rand.c')
-rw-r--r--Cryptlib/OpenSSL/crypto/rand/md_rand.c540
1 files changed, 233 insertions, 307 deletions
diff --git a/Cryptlib/OpenSSL/crypto/rand/md_rand.c b/Cryptlib/OpenSSL/crypto/rand/md_rand.c
index 85ce4e6f..bd76e23e 100644
--- a/Cryptlib/OpenSSL/crypto/rand/md_rand.c
+++ b/Cryptlib/OpenSSL/crypto/rand/md_rand.c
@@ -1,38 +1,134 @@
-/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+/* crypto/rand/md_rand.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.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
+ * 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.]
*/
+/* ====================================================================
+ * Copyright (c) 1998-2001 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above 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 acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#define OPENSSL_FIPSEVP
+#ifdef MD_RAND_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "e_os.h"
-#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_DSPBIOS))
-# include <sys/time.h>
-#endif
-#if defined(OPENSSL_SYS_VXWORKS)
-# include <time.h>
-#endif
-
-#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>
-#include <openssl/async.h>
#include "rand_lcl.h"
#include <openssl/err.h>
-#include <internal/thread_once.h>
-
-#ifdef OPENSSL_FIPS
-# include <openssl/fips.h>
-#endif
-
#ifdef BN_DEBUG
# define PREDICT
#endif
@@ -48,59 +144,41 @@ static long md_count[2] = { 0, 0 };
static double entropy = 0;
static int initialized = 0;
-static CRYPTO_RWLOCK *rand_lock = NULL;
-static CRYPTO_RWLOCK *rand_tmp_lock = NULL;
-static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
-
-/* May be set only when a thread holds rand_lock (to prevent double locking) */
-static unsigned int crypto_lock_rand = 0;
-/* access to locking_threadid is synchronized by rand_tmp_lock */
+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 */
/* valid iff crypto_lock_rand is set */
-static CRYPTO_THREAD_ID locking_threadid;
+static CRYPTO_THREADID locking_threadid;
#ifdef PREDICT
int rand_predictable = 0;
#endif
-static int rand_hw_seed(EVP_MD_CTX *ctx);
-
-static void rand_cleanup(void);
-static int rand_seed(const void *buf, int num);
-static int rand_add(const void *buf, int num, double add_entropy);
-static int rand_bytes(unsigned char *buf, int num, int pseudo);
-static int rand_nopseudo_bytes(unsigned char *buf, int num);
-#if OPENSSL_API_COMPAT < 0x10100000L
-static int rand_pseudo_bytes(unsigned char *buf, int num);
-#endif
-static int rand_status(void);
-
-static RAND_METHOD rand_meth = {
- rand_seed,
- rand_nopseudo_bytes,
- rand_cleanup,
- rand_add,
-#if OPENSSL_API_COMPAT < 0x10100000L
- rand_pseudo_bytes,
-#else
- NULL,
-#endif
- rand_status
+const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT;
+
+static void ssleay_rand_cleanup(void);
+static void ssleay_rand_seed(const void *buf, int num);
+static void ssleay_rand_add(const void *buf, int num, double add_entropy);
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
+static int ssleay_rand_status(void);
+
+RAND_METHOD rand_ssleay_meth = {
+ ssleay_rand_seed,
+ ssleay_rand_nopseudo_bytes,
+ ssleay_rand_cleanup,
+ ssleay_rand_add,
+ ssleay_rand_pseudo_bytes,
+ ssleay_rand_status
};
-DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
-{
- OPENSSL_init_crypto(0, NULL);
- rand_lock = CRYPTO_THREAD_lock_new();
- rand_tmp_lock = CRYPTO_THREAD_lock_new();
- return rand_lock != NULL && rand_tmp_lock != NULL;
-}
-
-RAND_METHOD *RAND_OpenSSL(void)
+RAND_METHOD *RAND_SSLeay(void)
{
- return (&rand_meth);
+ return (&rand_ssleay_meth);
}
-static void rand_cleanup(void)
+static void ssleay_rand_cleanup(void)
{
OPENSSL_cleanse(state, sizeof(state));
state_num = 0;
@@ -110,21 +188,18 @@ static void rand_cleanup(void)
md_count[1] = 0;
entropy = 0;
initialized = 0;
- CRYPTO_THREAD_lock_free(rand_lock);
- CRYPTO_THREAD_lock_free(rand_tmp_lock);
}
-static int rand_add(const void *buf, int num, double add)
+static void ssleay_rand_add(const void *buf, int num, double add)
{
int i, j, k, st_idx;
long md_c[2];
unsigned char local_md[MD_DIGEST_LENGTH];
- EVP_MD_CTX *m;
+ EVP_MD_CTX m;
int do_not_lock;
- int rv = 0;
if (!num)
- return 1;
+ return;
/*
* (Based on the rand(3) manpage)
@@ -141,24 +216,18 @@ static int rand_add(const void *buf, int num, double add)
* hash function.
*/
- m = EVP_MD_CTX_new();
- if (m == NULL)
- goto err;
-
- if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
- goto err;
-
/* check if we already have the lock */
if (crypto_lock_rand) {
- CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
- CRYPTO_THREAD_read_lock(rand_tmp_lock);
- do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
- CRYPTO_THREAD_unlock(rand_tmp_lock);
+ CRYPTO_THREADID cur;
+ CRYPTO_THREADID_current(&cur);
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+ do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
} else
do_not_lock = 0;
if (!do_not_lock)
- CRYPTO_THREAD_write_lock(rand_lock);
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
st_idx = state_index;
/*
@@ -190,28 +259,24 @@ static int rand_add(const void *buf, int num, double add)
md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
if (!do_not_lock)
- CRYPTO_THREAD_unlock(rand_lock);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ EVP_MD_CTX_init(&m);
for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
j = (num - i);
j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
- if (!MD_Init(m))
- goto err;
- if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
- goto err;
+ MD_Init(&m);
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
k = (st_idx + j) - STATE_SIZE;
if (k > 0) {
- if (!MD_Update(m, &(state[st_idx]), j - k))
- goto err;
- if (!MD_Update(m, &(state[0]), k))
- goto err;
- } else if (!MD_Update(m, &(state[st_idx]), j))
- goto err;
+ MD_Update(&m, &(state[st_idx]), j - k);
+ MD_Update(&m, &(state[0]), k);
+ } else
+ MD_Update(&m, &(state[st_idx]), j);
/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
- if (!MD_Update(m, buf, j))
- goto err;
+ 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,
@@ -220,10 +285,8 @@ static int rand_add(const void *buf, int num, double add)
* insecure keys.
*/
- if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
- goto err;
- if (!MD_Final(m, local_md))
- goto err;
+ MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+ MD_Final(&m, local_md);
md_c[1]++;
buf = (const char *)buf + j;
@@ -232,7 +295,7 @@ static int rand_add(const void *buf, int num, double add)
/*
* Parallel threads may interfere with this, but always each byte
* of the new state is the XOR of some previous value of its and
- * local_md (intermediate values may be lost). Alway using locking
+ * local_md (itermediate values may be lost). Alway using locking
* could hurt performance more than necessary given that
* conflicts occur only when the total seeding is longer than the
* random state.
@@ -242,9 +305,10 @@ static int rand_add(const void *buf, int num, double add)
st_idx = 0;
}
}
+ EVP_MD_CTX_cleanup(&m);
if (!do_not_lock)
- CRYPTO_THREAD_write_lock(rand_lock);
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
/*
* Don't just copy back local_md into md -- this could mean that other
* thread's seeding remains without effect (except for the incremented
@@ -257,20 +321,19 @@ static int rand_add(const void *buf, int num, double add)
if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
entropy += add;
if (!do_not_lock)
- CRYPTO_THREAD_unlock(rand_lock);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- rv = 1;
- err:
- EVP_MD_CTX_free(m);
- return rv;
+#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
+ assert(md_c[1] == md_count[1]);
+#endif
}
-static int rand_seed(const void *buf, int num)
+static void ssleay_rand_seed(const void *buf, int num)
{
- return rand_add(buf, num, (double)num);
+ ssleay_rand_add(buf, num, (double)num);
}
-static int rand_bytes(unsigned char *buf, int num, int pseudo)
+int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
{
static volatile int stirred_pool = 0;
int i, j, k;
@@ -278,32 +341,11 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
int ok;
long md_c[2];
unsigned char local_md[MD_DIGEST_LENGTH];
- EVP_MD_CTX *m;
+ EVP_MD_CTX m;
#ifndef GETPID_IS_MEANINGLESS
pid_t curr_pid = getpid();
#endif
- time_t curr_time = time(NULL);
int do_stir_pool = 0;
-/* time value for various platforms */
-#ifdef OPENSSL_SYS_WIN32
- FILETIME tv;
-# ifdef _WIN32_WCE
- SYSTEMTIME t;
- GetSystemTime(&t);
- SystemTimeToFileTime(&t, &tv);
-# else
- GetSystemTimeAsFileTime(&tv);
-# endif
-#elif defined(OPENSSL_SYS_VXWORKS)
- struct timespec tv;
- clock_gettime(CLOCK_REALTIME, &ts);
-#elif defined(OPENSSL_SYS_DSPBIOS)
- unsigned long long tv, OPENSSL_rdtsc();
- tv = OPENSSL_rdtsc();
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
-#endif
#ifdef PREDICT
if (rand_predictable) {
@@ -318,10 +360,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
if (num <= 0)
return 1;
- m = EVP_MD_CTX_new();
- if (m == NULL)
- goto err_mem;
-
+ EVP_MD_CTX_init(&m);
/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
num_ceil =
(1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
@@ -343,21 +382,13 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
* are fed into the hash function and the results are kept in the
* global 'md'.
*/
+ if (lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
- goto err_mem;
-
- CRYPTO_THREAD_write_lock(rand_lock);
- /*
- * We could end up in an async engine while holding this lock so ensure
- * we don't pause and cause a deadlock
- */
- ASYNC_block_pause();
-
- /* prevent rand_bytes() from trying to obtain the lock again */
- CRYPTO_THREAD_write_lock(rand_tmp_lock);
- locking_threadid = CRYPTO_THREAD_get_current_id();
- CRYPTO_THREAD_unlock(rand_tmp_lock);
+ /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+ CRYPTO_THREADID_current(&locking_threadid);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
if (!initialized) {
@@ -391,7 +422,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
* In the output function only half of 'md' remains secret, so we
* better make sure that the required entropy gets 'evenly
* distributed' through 'state', our randomness pool. The input
- * function (rand_add) chains all of 'md', which makes it more
+ * function (ssleay_rand_add) chains all of 'md', which makes it more
* suitable for this purpose.
*/
@@ -403,9 +434,9 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
/*
* Note that the seed does not matter, it's just that
- * rand_add expects to have something to hash.
+ * ssleay_rand_add expects to have something to hash.
*/
- rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
+ ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
n -= MD_DIGEST_LENGTH;
}
if (ok)
@@ -431,46 +462,41 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
/* before unlocking, we must clear 'crypto_lock_rand' */
crypto_lock_rand = 0;
- ASYNC_unblock_pause();
- CRYPTO_THREAD_unlock(rand_lock);
+ if (lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
while (num > 0) {
/* num_ceil -= MD_DIGEST_LENGTH/2 */
j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
num -= j;
- if (!MD_Init(m))
- goto err;
+ MD_Init(&m);
#ifndef GETPID_IS_MEANINGLESS
if (curr_pid) { /* just in the first iteration to save time */
- if (!MD_Update(m, (unsigned char *)&curr_pid, sizeof curr_pid))
- goto err;
+ MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid);
curr_pid = 0;
}
#endif
- if (curr_time) { /* just in the first iteration to save time */
- if (!MD_Update(m, (unsigned char *)&curr_time, sizeof curr_time))
- goto err;
- if (!MD_Update(m, (unsigned char *)&tv, sizeof tv))
- goto err;
- curr_time = 0;
- if (!rand_hw_seed(m))
- goto err;
- }
- if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
- goto err;
- if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
- goto err;
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+
+#ifndef PURIFY /* purify complains */
+ /*
+ * The following line uses the supplied buffer as a small source of
+ * entropy: since this buffer is often uninitialised it may cause
+ * programs such as purify or valgrind to complain. So for those
+ * builds it is not used: the removal of such a small source of
+ * entropy has negligible impact on security.
+ */
+ MD_Update(&m, buf, j);
+#endif
k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
if (k > 0) {
- if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
- goto err;
- if (!MD_Update(m, &(state[0]), k))
- goto err;
- } else if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
- goto err;
- if (!MD_Final(m, local_md))
- goto err;
+ MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k);
+ MD_Update(&m, &(state[0]), k);
+ } else
+ MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2);
+ MD_Final(&m, local_md);
for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
/* may compete with other threads */
@@ -482,93 +508,69 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
}
}
- if (!MD_Init(m)
- || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
- || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
- goto err;
- CRYPTO_THREAD_write_lock(rand_lock);
- /*
- * Prevent deadlocks if we end up in an async engine
- */
- ASYNC_block_pause();
- if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
- CRYPTO_THREAD_unlock(rand_lock);
- goto err;
- }
- ASYNC_unblock_pause();
- CRYPTO_THREAD_unlock(rand_lock);
-
- EVP_MD_CTX_free(m);
+ MD_Init(&m);
+ MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+ MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ if (lock)
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ MD_Update(&m, md, MD_DIGEST_LENGTH);
+ MD_Final(&m, md);
+ if (lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ EVP_MD_CTX_cleanup(&m);
if (ok)
return (1);
else if (pseudo)
return 0;
else {
- RANDerr(RAND_F_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
+ RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
- "https://www.openssl.org/docs/faq.html");
+ "http://www.openssl.org/support/faq.html");
return (0);
}
- err:
- RANDerr(RAND_F_RAND_BYTES, ERR_R_EVP_LIB);
- EVP_MD_CTX_free(m);
- return 0;
- err_mem:
- RANDerr(RAND_F_RAND_BYTES, ERR_R_MALLOC_FAILURE);
- EVP_MD_CTX_free(m);
- return 0;
-
}
-static int rand_nopseudo_bytes(unsigned char *buf, int num)
+static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
{
- return rand_bytes(buf, num, 0);
+ return ssleay_rand_bytes(buf, num, 0, 1);
}
-#if OPENSSL_API_COMPAT < 0x10100000L
/*
* pseudo-random bytes that are guaranteed to be unique but not unpredictable
*/
-static int rand_pseudo_bytes(unsigned char *buf, int num)
+static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
{
- return rand_bytes(buf, num, 1);
+ return ssleay_rand_bytes(buf, num, 1, 1);
}
-#endif
-static int rand_status(void)
+static int ssleay_rand_status(void)
{
- CRYPTO_THREAD_ID cur;
+ CRYPTO_THREADID cur;
int ret;
int do_not_lock;
- if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
- return 0;
-
- cur = CRYPTO_THREAD_get_current_id();
+ 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_THREAD_read_lock(rand_tmp_lock);
- do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
- CRYPTO_THREAD_unlock(rand_tmp_lock);
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
+ do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
} else
do_not_lock = 0;
if (!do_not_lock) {
- CRYPTO_THREAD_write_lock(rand_lock);
- /*
- * Prevent deadlocks in case we end up in an async engine
- */
- ASYNC_block_pause();
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
/*
- * prevent rand_bytes() from trying to obtain the lock again
+ * prevent ssleay_rand_bytes() from trying to obtain the lock again
*/
- CRYPTO_THREAD_write_lock(rand_tmp_lock);
- locking_threadid = cur;
- CRYPTO_THREAD_unlock(rand_tmp_lock);
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
+ CRYPTO_THREADID_cpy(&locking_threadid, &cur);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
}
@@ -583,84 +585,8 @@ static int rand_status(void)
/* before unlocking, we must clear 'crypto_lock_rand' */
crypto_lock_rand = 0;
- ASYNC_unblock_pause();
- CRYPTO_THREAD_unlock(rand_lock);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
}
return ret;
}
-
-/*
- * rand_hw_seed: get seed data from any available hardware RNG. only
- * currently supports rdrand.
- */
-
-/* Adapted from eng_rdrand.c */
-
-#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || \
- defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) \
- && !defined(OPENSSL_NO_RDRAND)
-
-# define RDRAND_CALLS 4
-
-size_t OPENSSL_ia32_rdrand(void);
-extern unsigned int OPENSSL_ia32cap_P[];
-
-static int rand_hw_seed(EVP_MD_CTX *ctx)
-{
- int i;
- if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
- return 1;
- for (i = 0; i < RDRAND_CALLS; i++) {
- size_t rnd;
- rnd = OPENSSL_ia32_rdrand();
- if (rnd == 0)
- return 1;
- if (!MD_Update(ctx, (unsigned char *)&rnd, sizeof(size_t)))
- return 0;
- }
- return 1;
-}
-
-/* XOR an existing buffer with random data */
-
-void rand_hw_xor(unsigned char *buf, size_t num)
-{
- size_t rnd;
- if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
- return;
- while (num >= sizeof(size_t)) {
- rnd = OPENSSL_ia32_rdrand();
- if (rnd == 0)
- return;
- *((size_t *)buf) ^= rnd;
- buf += sizeof(size_t);
- num -= sizeof(size_t);
- }
- if (num) {
- rnd = OPENSSL_ia32_rdrand();
- if (rnd == 0)
- return;
- while (num) {
- *buf ^= rnd & 0xff;
- rnd >>= 8;
- buf++;
- num--;
- }
- }
-}
-
-#else
-
-static int rand_hw_seed(EVP_MD_CTX *ctx)
-{
- return 1;
-}
-
-void rand_hw_xor(unsigned char *buf, size_t num)
-{
- return;
-}
-
-#endif