summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/random.c49
-rw-r--r--include/linux/random.h2
-rw-r--r--lib/vsprintf.c7
3 files changed, 20 insertions, 38 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7ec700683e42..6b8c89378954 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -433,12 +433,9 @@ static void _get_random_bytes(void *buf, size_t len)
/*
* This function is the exported kernel interface. It returns some
* number of good random numbers, suitable for key generation, seeding
- * TCP sequence numbers, etc. It does not rely on the hardware random
- * number generator. For random bytes direct from the hardware RNG
- * (when available), use get_random_bytes_arch(). In order to ensure
- * that the randomness provided by this function is okay, the function
- * wait_for_random_bytes() should be called and return 0 at least once
- * at any point prior.
+ * TCP sequence numbers, etc. In order to ensure that the randomness
+ * by this function is okay, the function wait_for_random_bytes()
+ * should be called and return 0 at least once at any point prior.
*/
void get_random_bytes(void *buf, size_t len)
{
@@ -655,33 +652,6 @@ unsigned long randomize_page(unsigned long start, unsigned long range)
return start + (get_random_long() % range << PAGE_SHIFT);
}
-/*
- * This function will use the architecture-specific hardware random
- * number generator if it is available. It is not recommended for
- * use. Use get_random_bytes() instead. It returns the number of
- * bytes filled in.
- */
-size_t __must_check get_random_bytes_arch(void *buf, size_t len)
-{
- size_t left = len;
- u8 *p = buf;
-
- while (left) {
- unsigned long v;
- size_t block_len = min_t(size_t, left, sizeof(unsigned long));
-
- if (!arch_get_random_long(&v))
- break;
-
- memcpy(p, &v, block_len);
- p += block_len;
- left -= block_len;
- }
-
- return len - left;
-}
-EXPORT_SYMBOL(get_random_bytes_arch);
-
/**********************************************************************
*
@@ -879,6 +849,7 @@ static void __cold _credit_init_bits(size_t bits)
*
**********************************************************************/
+static bool used_arch_random;
static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
static int __init parse_trust_cpu(char *arg)
@@ -956,6 +927,7 @@ int __init random_init(const char *command_line)
crng_reseed();
else if (trust_cpu)
credit_init_bits(arch_bytes * 8);
+ used_arch_random = arch_bytes * 8 >= POOL_READY_BITS;
WARN_ON(register_pm_notifier(&pm_notifier));
@@ -965,6 +937,17 @@ int __init random_init(const char *command_line)
}
/*
+ * Returns whether arch randomness has been mixed into the initial
+ * state of the RNG, regardless of whether or not that randomness
+ * was credited. Knowing this is only good for a very limited set
+ * of uses, such as early init printk pointer obfuscation.
+ */
+bool rng_has_arch_random(void)
+{
+ return used_arch_random;
+}
+
+/*
* Add device- or boot-specific data to the input pool to help
* initialize it.
*
diff --git a/include/linux/random.h b/include/linux/random.h
index fc82f1dc36f1..6af130c6edb9 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -38,7 +38,6 @@ static inline int unregister_random_vmfork_notifier(struct notifier_block *nb) {
#endif
void get_random_bytes(void *buf, size_t len);
-size_t __must_check get_random_bytes_arch(void *buf, size_t len);
u32 get_random_u32(void);
u64 get_random_u64(void);
static inline unsigned int get_random_int(void)
@@ -77,6 +76,7 @@ unsigned long randomize_page(unsigned long start, unsigned long range);
int __init random_init(const char *command_line);
bool rng_is_initialized(void);
+bool rng_has_arch_random(void);
int wait_for_random_bytes(void);
int register_random_ready_notifier(struct notifier_block *nb);
int unregister_random_ready_notifier(struct notifier_block *nb);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 40d26a07a133..20e9887faaaa 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -776,12 +776,11 @@ static struct notifier_block random_ready = {
static int __init initialize_ptr_random(void)
{
- int key_size = sizeof(ptr_key);
int ret;
- /* Use hw RNG if available. */
- if (get_random_bytes_arch(&ptr_key, key_size) == key_size) {
- static_branch_disable(&not_filled_random_ptr_key);
+ /* Don't bother waiting for RNG to be ready if RDRAND is mixed in already. */
+ if (rng_has_arch_random()) {
+ enable_ptr_key_workfn(&enable_ptr_key_work);
return 0;
}