diff options
author | Robbie Harwood <rharwood@redhat.com> | 2016-09-12 12:25:05 -0400 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2016-09-22 13:38:52 -0400 |
commit | 0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f (patch) | |
tree | e68e51dc835fbc56cbd1368b6def0ab6ce1300f6 | |
parent | f208d94e2b99945023ac4c3dfad35b85aba41760 (diff) | |
download | krb5-0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f.zip krb5-0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f.tar.gz krb5-0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f.tar.bz2 |
Don't feed OS RNG output into the OS RNG
krb5_c_random_os_entropy() now must be provided by PRNG modules.
ticket: 8499
-rw-r--r-- | src/lib/crypto/krb/crypto_int.h | 3 | ||||
-rw-r--r-- | src/lib/crypto/krb/prng.c | 60 | ||||
-rw-r--r-- | src/lib/crypto/krb/prng_fortuna.c | 26 | ||||
-rw-r--r-- | 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; +} |