Entropie geht nicht nur über verloren /dev/{,u}random
, der Kernel nimmt auch einige auf. Beispielsweise haben neue Prozesse zufällige Adressen (ASLR) und Netzwerkpakete benötigen zufällige Folgenummern. Sogar das Dateisystemmodul kann Entropie entfernen. Siehe die Kommentare in drivers / char / random.c . Beachten Sie auch, dass entropy_avail
sich dies auf den Eingabe-Pool bezieht , nicht auf die Ausgabe-Pools (im Grunde genommen nicht blockierend /dev/urandom
und blockierend /dev/random
).
Wenn Sie den Entropiepool überwachen müssen, verwenden Sie nicht watch cat
, da dieser bei jedem Aufruf von Entropie verbraucht cat
. In der Vergangenheit wollte ich auch diesen Pool beobachten, da GPG beim Generieren von Schlüsseln sehr langsam war. Deshalb schrieb ich ein C-Programm mit dem einzigen Zweck, den Entropiepool zu beobachten: https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c .
Beachten Sie, dass es Hintergrundprozesse geben kann, die auch Entropie verbrauchen. Mithilfe von Tracepoints auf einem geeigneten Kernel können Sie die Prozesse anzeigen, die den Entropiepool ändern. Beispielverwendung, bei der alle mit dem zufälligen Subsystem zusammenhängenden Tracepoints aufgezeichnet werden, einschließlich der Callchain ( -g
) auf allen CPUs ( -a
), die nach 1 Sekunde mit der Messung beginnen, um ihren eigenen Prozess ( -D 1000
) zu ignorieren, und einschließlich Zeitstempel ( -T
):
sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
Lesen Sie es mit einem dieser Befehle (ändern Sie den Eigentümer perf.data
nach Bedarf):
perf report # opens an interactive overview
perf script # outputs events after each other with traces
Die perf script
Ausgabe gibt einen interessanten Einblick und zeigt, wann in regelmäßigen Abständen ca. 8 Byte (64 Bit) Entropie auf meinem Computer verbraucht werden:
kworker / 0: 2 193 3292.235908: random: extract_entropy: ffffffff8173e956 pool: nbytes 8 entropy_count 921 caller _xfer_secondary_pool
5eb857 extract_entropy (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb984 _xfer_secondary_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ebae6 push_to_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293a05 process_one_work (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293ce8 worker_thread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
299998 kthread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7482 ret_from_fork (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
kworker / 0: 2 193 [000] 3292.235911: random: debit_entropy: ffffffff8173e956: debit_bits 64
5eb3e8 account.part.12 (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb770 extract_entropy (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5eb984 _xfer_secondary_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ebae6 push_to_pool (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293a05 process_one_work (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
293ce8 worker_thread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
299998 kthread (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7482 ret_from_fork (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
...
swapper 0 3292.507720: random: credit_entropy_bits: ffffffff8173e956 pool: bits 2 entropy_count 859 entropy_total 2 caller add_interrupt_randomness
5eaab6 credit_entropy_bits (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
5ec644 add_interrupt_randomness (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d5729 handle_irq_event_percpu (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d58b9 handle_irq_event (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d8d1b handle_edge_irq (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
230e6a handle_irq (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c9abb do_IRQ (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
7c7bc2 ret_from_intr (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
6756c7 cpuidle_enter (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2bd9fa call_cpuidle (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2bde18 cpu_startup_entry (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2510e5 start_secondary (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
Anscheinend geschieht dies, um eine Verschwendung von Entropie zu verhindern, indem Entropie vom Eingabepool in Ausgabepools übertragen wird:
/*
* Credit (or debit) the entropy store with n bits of entropy.
* Use credit_entropy_bits_safe() if the value comes from userspace
* or otherwise should be checked for extreme values.
*/
static void credit_entropy_bits(struct entropy_store *r, int nbits)
{
...
/* If the input pool is getting full, send some
* entropy to the two output pools, flipping back and
* forth between them, until the output pools are 75%
* full.
*/
...
schedule_work(&last->push_work);
}
/*
* Used as a workqueue function so that when the input pool is getting
* full, we can "spill over" some entropy to the output pools. That
* way the output pools can store some of the excess entropy instead
* of letting it go to waste.
*/
static void push_to_pool(struct work_struct *work)
{
...
}
/dev/random
ist schließlich etwas, das für sichere kryptografische Zwecke verwendet wird, und die Implementierung kann es sich nicht leisten, naiv zu sein. Eine Erklärung könnte im letzten Punkt hier angedeutet werden: de.wikipedia.org/wiki/Entropy_pool#Using_observed_events (beginnend mit "Verwalten einer Stream-Chiffre mit einem Schlüssel und einem Initialisierungsvektor ...") -> Der Pool wird immer dann ersetzt, wenn es ausreicht Daten haben sich angesammelt.