forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'random-5.18-rc1-for-linus' of git://git.kernel.org/pub/scm…
…/linux/kernel/git/crng/random Pull random number generator updates from Jason Donenfeld: "There have been a few important changes to the RNG's crypto, but the intent for 5.18 has been to shore up the existing design as much as possible with modern cryptographic functions and proven constructions, rather than actually changing up anything fundamental to the RNG's design. So it's still the same old RNG at its core as before: it still counts entropy bits, and collects from the various sources with the same heuristics as before, and so forth. However, the cryptographic algorithms that transform that entropic data into safe random numbers have been modernized. Just as important, if not more, is that the code has been cleaned up and re-documented. As one of the first drivers in Linux, going back to 1.3.30, its general style and organization was showing its age and becoming both a maintenance burden and an auditability impediment. Hopefully this provides a more solid foundation to build on for the future. I encourage you to open up the file in full, and maybe you'll remark, "oh, that's what it's doing," and enjoy reading it. That, at least, is the eventual goal, which this pull begins working toward. Here's a summary of the various patches in this pull: - /dev/urandom and /dev/random now do the same thing, per the patch we discussed on the list. I think this is worth trying out. If it does appear problematic, I've made sure to keep it standalone and revertible without any conflicts. - Fixes and cleanups for numerous integer type problems, locking issues, and general code quality concerns. - The input pool's LFSR has been replaced with a cryptographically secure hash function, which has security and performance benefits alike, and consequently allows us to count entropy bits linearly. - The pre-init injection now uses a real hash function too, instead of an LFSR or vanilla xor. - The interrupt handler's fast_mix() function now uses one round of SipHash, rather than the fake crypto that was there before. - All additions of RDRAND and RDSEED now go through the input pool's hash function, in part to mitigate ridiculous hypothetical CPU backdoors, but more so to have a consistent interface for ingesting entropy that's easy to analyze, making everything happen one way, instead of a potpourri of different ways. - The crng now works on per-cpu data, while also being in accordance with the actual "fast key erasure RNG" design. This allows us to fix several boot-time race complications associated with the prior dynamically allocated model, eliminates much locking, and makes our backtrack protection more robust. - Batched entropy now erases doled out values so that it's backtrack resistant. - Working closely with Sebastian, the interrupt handler no longer needs to take any locks at all, as we punt the synchronized/expensive operations to a workqueue. This is especially nice for PREEMPT_RT, where taking spinlocks in irq context is problematic. It also makes the handler faster for the rest of us. - Also working with Sebastian, we now do the right thing on CPU hotplug, so that we don't use stale entropy or fail to accumulate new entropy when CPUs come back online. - We handle virtual machines that fork / clone / snapshot, using the "vmgenid" ACPI specification for retrieving a unique new RNG seed, which we can use to also make WireGuard (and in the future, other things) safe across VM forks. - Around boot time, we now try to reseed more often if enough entropy is available, before settling on the usual 5 minute schedule. - Last, but certainly not least, the documentation in the file has been updated considerably" * tag 'random-5.18-rc1-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random: (60 commits) random: check for signal and try earlier when generating entropy random: reseed more often immediately after booting random: make consistent usage of crng_ready() random: use SipHash as interrupt entropy accumulator wireguard: device: clear keys on VM fork random: provide notifier for VM fork random: replace custom notifier chain with standard one random: do not export add_vmfork_randomness() unless needed virt: vmgenid: notify RNG of VM fork and supply generation ID ACPI: allow longer device IDs random: add mechanism for VM forks to reinitialize crng random: don't let 644 read-only sysctls be written to random: give sysctl_random_min_urandom_seed a more sensible value random: block in /dev/urandom random: do crng pre-init loading in worker rather than irq random: unify cycles_t and jiffies usage and types random: cleanup UUID handling random: only wake up writers after zap if threshold was passed random: round-robin registers as ulong, not u32 random: clear fast pool, crng, and batches in cpuhp bring up ...
- Loading branch information
Showing
17 changed files
with
1,419 additions
and
2,007 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16213,6 +16213,7 @@ M: Jason A. Donenfeld <[email protected]> | |
T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git | ||
S: Maintained | ||
F: drivers/char/random.c | ||
F: drivers/virt/vmgenid.c | ||
|
||
RAPIDIO SUBSYSTEM | ||
M: Matt Porter <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2022 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
* | ||
* The "Virtual Machine Generation ID" is exposed via ACPI and changes when a | ||
* virtual machine forks or is cloned. This driver exists for shepherding that | ||
* information to random.c. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/acpi.h> | ||
#include <linux/random.h> | ||
|
||
ACPI_MODULE_NAME("vmgenid"); | ||
|
||
enum { VMGENID_SIZE = 16 }; | ||
|
||
struct vmgenid_state { | ||
u8 *next_id; | ||
u8 this_id[VMGENID_SIZE]; | ||
}; | ||
|
||
static int vmgenid_add(struct acpi_device *device) | ||
{ | ||
struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER }; | ||
struct vmgenid_state *state; | ||
union acpi_object *obj; | ||
phys_addr_t phys_addr; | ||
acpi_status status; | ||
int ret = 0; | ||
|
||
state = devm_kmalloc(&device->dev, sizeof(*state), GFP_KERNEL); | ||
if (!state) | ||
return -ENOMEM; | ||
|
||
status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed); | ||
if (ACPI_FAILURE(status)) { | ||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR")); | ||
return -ENODEV; | ||
} | ||
obj = parsed.pointer; | ||
if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2 || | ||
obj->package.elements[0].type != ACPI_TYPE_INTEGER || | ||
obj->package.elements[1].type != ACPI_TYPE_INTEGER) { | ||
ret = -EINVAL; | ||
goto out; | ||
} | ||
|
||
phys_addr = (obj->package.elements[0].integer.value << 0) | | ||
(obj->package.elements[1].integer.value << 32); | ||
state->next_id = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB); | ||
if (IS_ERR(state->next_id)) { | ||
ret = PTR_ERR(state->next_id); | ||
goto out; | ||
} | ||
|
||
memcpy(state->this_id, state->next_id, sizeof(state->this_id)); | ||
add_device_randomness(state->this_id, sizeof(state->this_id)); | ||
|
||
device->driver_data = state; | ||
|
||
out: | ||
ACPI_FREE(parsed.pointer); | ||
return ret; | ||
} | ||
|
||
static void vmgenid_notify(struct acpi_device *device, u32 event) | ||
{ | ||
struct vmgenid_state *state = acpi_driver_data(device); | ||
u8 old_id[VMGENID_SIZE]; | ||
|
||
memcpy(old_id, state->this_id, sizeof(old_id)); | ||
memcpy(state->this_id, state->next_id, sizeof(state->this_id)); | ||
if (!memcmp(old_id, state->this_id, sizeof(old_id))) | ||
return; | ||
add_vmfork_randomness(state->this_id, sizeof(state->this_id)); | ||
} | ||
|
||
static const struct acpi_device_id vmgenid_ids[] = { | ||
{ "VM_GEN_COUNTER", 0 }, | ||
{ } | ||
}; | ||
|
||
static struct acpi_driver vmgenid_driver = { | ||
.name = "vmgenid", | ||
.ids = vmgenid_ids, | ||
.owner = THIS_MODULE, | ||
.ops = { | ||
.add = vmgenid_add, | ||
.notify = vmgenid_notify | ||
} | ||
}; | ||
|
||
module_acpi_driver(vmgenid_driver); | ||
|
||
MODULE_DEVICE_TABLE(acpi, vmgenid_ids); | ||
MODULE_DESCRIPTION("Virtual Machine Generation ID"); | ||
MODULE_LICENSE("GPL v2"); | ||
MODULE_AUTHOR("Jason A. Donenfeld <[email protected]>"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.