188 lines
5.8 KiB
Diff
188 lines
5.8 KiB
Diff
From dd0c141bfc858caa8470271205220a968db7ab51 Mon Sep 17 00:00:00 2001
|
|
From: Robbie Harwood <rharwood@redhat.com>
|
|
Date: Mon, 12 Sep 2016 12:25:05 -0400
|
|
Subject: [PATCH] Don't feed OS RNG output into the OS RNG
|
|
|
|
krb5_c_random_os_entropy() now must be provided by PRNG modules.
|
|
|
|
ticket: 8499
|
|
(cherry picked from commit 0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f)
|
|
---
|
|
src/lib/crypto/krb/crypto_int.h | 3 +-
|
|
src/lib/crypto/krb/prng.c | 60 +++++----------------------------------
|
|
src/lib/crypto/krb/prng_fortuna.c | 26 ++++++++++++++++-
|
|
src/lib/crypto/krb/prng_os.c | 6 ++++
|
|
4 files changed, 40 insertions(+), 55 deletions(-)
|
|
|
|
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
|
|
index c054144..a205e3f 100644
|
|
--- a/src/lib/crypto/krb/crypto_int.h
|
|
+++ b/src/lib/crypto/krb/crypto_int.h
|
|
@@ -508,6 +508,7 @@ void krb5int_crypto_impl_cleanup(void);
|
|
* PRNG modules must implement the following APIs from krb5.h:
|
|
* krb5_c_random_add_entropy
|
|
* krb5_c_random_make_octets
|
|
+ * krb5_c_random_os_entropy
|
|
*
|
|
* PRNG modules should implement these functions. They are called from the
|
|
* crypto library init and cleanup functions, and can be used to setup and tear
|
|
@@ -517,7 +518,7 @@ int k5_prng_init(void);
|
|
void k5_prng_cleanup(void);
|
|
|
|
/* Used by PRNG modules to gather OS entropy. Returns true on success. */
|
|
-krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len);
|
|
+krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len, int strong);
|
|
|
|
/*** Inline helper functions ***/
|
|
|
|
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
|
|
index e478b19..9ad24c1 100644
|
|
--- a/src/lib/crypto/krb/prng.c
|
|
+++ b/src/lib/crypto/krb/prng.c
|
|
@@ -36,11 +36,13 @@ krb5_c_random_seed(krb5_context context, krb5_data *data)
|
|
#if defined(_WIN32)
|
|
|
|
krb5_boolean
|
|
-k5_get_os_entropy(unsigned char *buf, size_t len)
|
|
+k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
|
|
{
|
|
krb5_boolean result;
|
|
HCRYPTPROV provider;
|
|
|
|
+ /* CryptGenRandom is always considered strong. */
|
|
+
|
|
if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
|
CRYPT_VERIFYCONTEXT))
|
|
return FALSE;
|
|
@@ -49,22 +51,6 @@ k5_get_os_entropy(unsigned char *buf, size_t len)
|
|
return result;
|
|
}
|
|
|
|
-krb5_error_code KRB5_CALLCONV
|
|
-krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
|
|
-{
|
|
- int oursuccess = 0;
|
|
- char buf[1024];
|
|
- krb5_data data = make_data(buf, sizeof(buf));
|
|
-
|
|
- if (k5_get_os_entropy(buf, sizeof(buf)) &&
|
|
- krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
|
|
- &data) == 0)
|
|
- oursuccess = 1;
|
|
- if (success != NULL)
|
|
- *success = oursuccess;
|
|
- return 0;
|
|
-}
|
|
-
|
|
#else /* not Windows */
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
@@ -107,44 +93,12 @@ cleanup:
|
|
}
|
|
|
|
krb5_boolean
|
|
-k5_get_os_entropy(unsigned char *buf, size_t len)
|
|
+k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
|
|
{
|
|
- return read_entropy_from_device("/dev/urandom", buf, len);
|
|
-}
|
|
+ const char *device;
|
|
|
|
-/* Read entropy from device and contribute it to the PRNG. Returns true on
|
|
- * success. */
|
|
-static krb5_boolean
|
|
-add_entropy_from_device(krb5_context context, const char *device)
|
|
-{
|
|
- krb5_data data;
|
|
- unsigned char buf[64];
|
|
-
|
|
- if (!read_entropy_from_device(device, buf, sizeof(buf)))
|
|
- return FALSE;
|
|
- data = make_data(buf, sizeof(buf));
|
|
- return (krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
|
|
- &data) == 0);
|
|
-}
|
|
-
|
|
-krb5_error_code KRB5_CALLCONV
|
|
-krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
|
|
-{
|
|
- int unused;
|
|
- int *oursuccess = (success != NULL) ? success : &unused;
|
|
-
|
|
- *oursuccess = 0;
|
|
- /* If we are getting strong data then try that first. We are
|
|
- guaranteed to cause a reseed of some kind if strong is true and
|
|
- we have both /dev/random and /dev/urandom. We want the strong
|
|
- data included in the reseed so we get it first.*/
|
|
- if (strong) {
|
|
- if (add_entropy_from_device(context, "/dev/random"))
|
|
- *oursuccess = 1;
|
|
- }
|
|
- if (add_entropy_from_device(context, "/dev/urandom"))
|
|
- *oursuccess = 1;
|
|
- return 0;
|
|
+ device = strong ? "/dev/random" : "/dev/urandom";
|
|
+ return read_entropy_from_device(device, buf, len);
|
|
}
|
|
|
|
#endif /* not Windows */
|
|
diff --git a/src/lib/crypto/krb/prng_fortuna.c b/src/lib/crypto/krb/prng_fortuna.c
|
|
index e70ffa3..017a119 100644
|
|
--- a/src/lib/crypto/krb/prng_fortuna.c
|
|
+++ b/src/lib/crypto/krb/prng_fortuna.c
|
|
@@ -366,7 +366,7 @@ k5_prng_init(void)
|
|
#else
|
|
last_pid = getpid();
|
|
#endif
|
|
- if (k5_get_os_entropy(osbuf, sizeof(osbuf))) {
|
|
+ if (k5_get_os_entropy(osbuf, sizeof(osbuf), 0)) {
|
|
generator_reseed(&main_state, osbuf, sizeof(osbuf));
|
|
have_entropy = TRUE;
|
|
}
|
|
@@ -443,4 +443,28 @@ krb5_c_random_make_octets(krb5_context context, krb5_data *outdata)
|
|
return 0;
|
|
}
|
|
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
|
|
+{
|
|
+ krb5_error_code ret;
|
|
+ krb5_data data;
|
|
+ uint8_t buf[64];
|
|
+ int status = 0;
|
|
+
|
|
+ if (!k5_get_os_entropy(buf, sizeof(buf), strong))
|
|
+ goto done;
|
|
+
|
|
+ data = make_data(buf, sizeof(buf));
|
|
+ ret = krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND, &data);
|
|
+ if (ret)
|
|
+ goto done;
|
|
+
|
|
+ status = 1;
|
|
+
|
|
+done:
|
|
+ if (success != NULL)
|
|
+ *success = status;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#endif /* not TEST */
|
|
diff --git a/src/lib/crypto/krb/prng_os.c b/src/lib/crypto/krb/prng_os.c
|
|
index 730ed2e..ecfe351 100644
|
|
--- a/src/lib/crypto/krb/prng_os.c
|
|
+++ b/src/lib/crypto/krb/prng_os.c
|
|
@@ -91,3 +91,9 @@ krb5_c_random_make_octets(krb5_context context, krb5_data *outdata)
|
|
}
|
|
return 0;
|
|
}
|
|
+
|
|
+krb5_error_code KRB5_CALLCONV
|
|
+krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
--
|
|
2.9.3
|
|
|