Entropy không chỉ bị mất qua /dev/{,u}random
, kernel cũng mất một số. Ví dụ, các quy trình mới có địa chỉ ngẫu nhiên (ASLR) và các gói mạng cần số thứ tự ngẫu nhiên. Ngay cả các mô-đun hệ thống tập tin có thể loại bỏ một số entropy. Xem các ý kiến trong trình điều khiển / char / Random.c . Cũng lưu ý rằng entropy_avail
đề cập đến nhóm đầu vào , không phải nhóm đầu ra (về cơ bản là không chặn /dev/urandom
và chặn /dev/random
).
Nếu bạn cần xem hồ bơi entropy, không sử dụng watch cat
, điều đó sẽ tiêu thụ entropy tại mỗi lần gọi cat
. Trước đây tôi cũng muốn xem nhóm này vì GPG rất chậm trong việc tạo khóa, do đó tôi đã viết một chương trình C với mục đích duy nhất là xem nhóm entropy: https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c .
Lưu ý rằng có thể có các quá trình nền cũng tiêu thụ entropy. Sử dụng tracepoints trên kernel phù hợp, bạn có thể thấy các quy trình sửa đổi nhóm entropy. Việc sử dụng ví dụ ghi lại tất cả các tracepoint liên quan đến hệ thống con ngẫu nhiên bao gồm callchain ( -g
) trên tất cả các CPU ( -a
) bắt đầu đo sau 1 giây để bỏ qua tiến trình của chính nó ( -D 1000
) và bao gồm cả dấu thời gian ( -T
):
sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
Đọc nó với một trong hai lệnh này (thay đổi chủ sở hữu perf.data
khi cần):
perf report # opens an interactive overview
perf script # outputs events after each other with traces
Đầu perf script
ra cung cấp một cái nhìn sâu sắc thú vị và hiển thị khi khoảng 8 byte (64 bit) entropy được rút hết định kỳ trên máy của tôi:
kworker / 0: 2 193 [000] 3292.235908: ngẫu nhiên: extract_entropy: ffffffff8173e956 pool: nbytes 8 entropy_count 921 người gọi _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: ngẫu nhiên: deb_entropy: ffffffff8173e956: deb_bits 64
Tài khoản 5eb3e8.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)
...
hoán đổi 0 [002] 3292.507720: ngẫu nhiên: credit_entropy_bits: ffffffff8173e956 pool: bits 2 entropy_count 859 entropy_total 2 người gọi 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 xử lý_irq_event_percpu (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d58b9 xử lý_irq_event (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
2d8d1b xử lý_edge_irq (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
230e6a xử lý_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 gọi_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)
Rõ ràng điều này xảy ra để ngăn chặn lãng phí entropy bằng cách chuyển entropy từ nhóm đầu vào sang nhóm đầu ra:
/*
* 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
xét cho cùng, một cái gì đó được sử dụng cho mục đích mã hóa an toàn và việc triển khai không thể ngây thơ. Một lời giải thích có thể được gợi ý ở điểm cuối cùng ở đây: en.wikipedia.org/wiki/Entropy_pool#Using_observed_events (bắt đầu bằng "Duy trì mật mã luồng bằng khóa và vectơ khởi tạo ...") -> nhóm được thay thế bất cứ khi nào đủ dữ liệu đã tích lũy.