Co powoduje drenaż entropii?

21

Jeśli tak, to watch cat /proc/sys/kernel/random/entropy_availwidzę, że entropia moich systemów z czasem powoli rośnie, aż osiągnie zakres 180-190, w którym to momencie spada do około 120-130. Krople w entropii zdają się pojawiać co około dwadzieścia sekund. Obserwuję to, nawet gdy lsofmówi, że żaden proces nie został otwarty /dev/randomlub /dev/urandomotwarty. Co drenuje entropię? Czy jądro również potrzebuje entropii, czy może przetwarza większą pulę w mniejszą, lepszej jakości?

To jest na komputerze bez systemu operacyjnego, bez połączeń SSL / SSH / WPA.

wingedsubmariner
źródło
Dobre pytanie i chociaż nie mogę udzielić konkretnej odpowiedzi, ma dla mnie sens, że „pula entropii” nie jest po prostu czymś, co powinno wzrosnąć, gdy nie jest używane. /dev/randomjest przecież czymś, co jest wykorzystywane do bezpiecznych celów kryptograficznych, a implementacja nie może być naiwna. Jednym z wyjaśnień może być wskazany w ostatnim punkcie tutaj: en.wikipedia.org/wiki/Entropy_pool#Using_observed_events (zaczynając od „Zachowaj szyfr strumienia za pomocą klucza i wektora inicjalizacji ...”) -> pula jest zastępowana, ilekroć wystarczająca dane się zgromadziły.
goldilocks,
Zauważ, że w każdym razie obliczanie entropii Linuksa /dev/randomjest dość fałszywe - gdy raz pula entropii zostanie zapełniona, /dev/urandomjest równie dobra jak /dev/random.
Gilles „SO- przestań być zły”
1
@techraf Wow, ta odpowiedź stała się bardzo szybka. Nigdy nie spodziewałem się, że otrzymam odpowiedź 2,5 roku później.
wingedsubmariner

Odpowiedzi:

20

Entropia jest nie tylko tracona przez /dev/{,u}randomjądro, ale także i jądro. Na przykład nowe procesy mają adresy losowe (ASLR), a pakiety sieciowe potrzebują losowych numerów sekwencji. Nawet moduł systemu plików może usunąć trochę entropii. Zobacz komentarze w drivers / char / random.c . Zauważ też, że entropy_availodnosi się to do puli wejściowej , a nie pul wyjściowych (w zasadzie nieblokujący /dev/urandomi blokujący /dev/random).

Jeśli chcesz obserwować pulę entropii, nie używaj watch cat, ponieważ zużyje ona entropii przy każdym wywołaniu cat. W przeszłości chciałem również oglądać tę pulę, ponieważ GPG bardzo wolno generowała klucze, dlatego napisałem program C, którego jedynym celem było obejrzenie puli entropii: https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c .

Zauważ, że mogą istnieć procesy w tle, które również zużywają entropię. Używając tracepoints na odpowiednim jądrze, możesz zobaczyć procesy modyfikujące pulę entropii. Przykładowe użycie, które rejestruje wszystkie punkty śledzenia związane z losowym podsystemem, w tym callchain ( -g) na wszystkich procesorach ( -a), rozpoczynając pomiar po 1 sekundzie w celu zignorowania własnego procesu ( -D 1000) i włączając znaczniki czasu ( -T):

sudo perf record -e random:\* -g -a -D 1000 -T sleep 60

Przeczytaj to za pomocą jednego z poniższych poleceń (w perf.datarazie potrzeby zmień właściciela ):

perf report  # opens an interactive overview
perf script  # outputs events after each other with traces

Dane perf scriptwyjściowe dają ciekawy wgląd i pokazują, kiedy około 8 bajtów (64 bitów) entropii jest okresowo usuwanych z mojej maszyny:

kworker / 0: 2 193 [000] 3292.235908: losowy: extract_entropy: ffffffff8173e956 pula: nbytes 8 entropy_count 921 rozmówca _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 [002] 3292.507720: losowy: bity_centralne_danych: ffffffff8173e956 pula: bity 2 entropia_liczenia 859 entropia_total 2 rozmówca 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 uchwyt_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)

Najwyraźniej dzieje się tak, aby zapobiec marnowaniu entropii, przenosząc entropię z puli wejściowej do pul wyjściowych:

/*
 * 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)
{
    ...
}
Lekensteyn
źródło
2
+1 za wskazanie, że nawet pozornie „niewinne” operacje, takie jak uruchomienie programu, mogą pozbawić niewielką ilość entropii.
CVn
To wyjaśnienie jest jednak trochę sprzeczne z sytuacją opisaną w pytaniu, prawda? Tam entropia (monitorowana watch) rośnie równomiernie, a następnie gwałtownie spada. Jeśli zostanie watchzużyta entropia przy każdym czytaniu, powinna się stopniowo zmniejszać.
techraf
@techraf Dobra obserwacja, okresowe wywoływanie catpowinno teoretycznie mieć taki sam odpływ entropii, który nie powinien być widoczny. Okazuje się, że entropia jest przenoszona do innej puli, gdy jest „wystarczająca” entropia.
Lekensteyn,
4

lsof nie jest najlepszym narzędziem do monitorowania,/dev/randomponieważ proces odczytu kończy się w bardzo krótkim czasie. Nie znam dobrej metody uzyskiwania informacji o tym, co robi proces odczytu, ale za jego pomocąinotifymożna monitorować, czy istnieje odczyt.

Oto w zasadzie dwa sposoby:

  1. Uzyskaj podsumowanie po N sekundach dzięki:

    inotifywatch -v -t 60 /dev/random 
    
  2. Zobacz wydarzenia z dostępem na żywo :

    inotifywait -m --timefmt '%H:%M:%S' --format '%T: %e' /dev/random
    

Żaden nie da ci procesu, a ten drugi nie da ci rozmiaru do przeczytania. Pierwszy daje podsumowanie jak w:

total  access  close_nowrite  open  filename
18     16      1              1     /dev/random

Jeśli masz to uruchomione i zrób to dd if=/dev/random of=/tmp/foo bs=1 count=3, masz pomysł.

W każdym razie. Nie da ci to tyknięć, gdy jądro zużyje się z puli.


Jeśli chodzi o sprawdzanie stanu entropii za pomocą

watch cat /proc/sys/kernel/random/entropy_avail

nie jest najlepszym pomysłem, ponieważ każdy catz nich pochłonie entropię. (Widzę, że pojawiła się kolejna odpowiedź, która również o tym wspomina.) Mam też do tego trochę kodu C i próbowałem go wczoraj znaleźć. Zobaczę, czy mogę to znaleźć i zaktualizować odpowiedź później.

Runium
źródło
Audyt może rejestrować odczyty /dev/random(wiem, że na tej stronie są podobne przykłady).
Gilles „SO- przestań być zły”
1
Co powiesz na użycie następującego perla zamiast watch cat : use Fcntl 'SEEK_SET'; open(my $fh,"<", "/proc/sys/kernel/random/entropy_avail"); while (1) { print <$fh>; sleep(1); seek($fh,0,SEEK_SET); }
gmatht