krb5 commit: Don't feed OS RNG output into the OS RNG
Greg Hudson
ghudson at mit.edu
Thu Sep 22 15:25:57 EDT 2016
https://github.com/krb5/krb5/commit/0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f
commit 0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f
Author: Robbie Harwood <rharwood at redhat.com>
Date: Mon Sep 12 12:25:05 2016 -0400
Don't feed OS RNG output into the OS RNG
krb5_c_random_os_entropy() now must be provided by PRNG modules.
ticket: 8499
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 e97c3cd..0f2e472 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -510,6 +510,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
@@ -519,7 +520,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;
+}
More information about the cvs-krb5
mailing list