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.


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)
{
    ...
}

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.