NAZWA

random, urandom - urządzenia źródłowe liczb losowych jądra

SKŁADNIA

#include <linux/random.h>
int ioctl(fd, RNDżądanie, parametr);

OPIS

Specjalne urządzenia znakowe /dev/random i /dev/urandom (obecne w Linuksie od wersji 1.3.30) stanowią interfejs do wbudowanego w jądro generatora liczb losowych. Plik /dev/random ma numer główny urządzenia 1 i numer poboczny 8. Plik /dev/urandom ma numer główny urządzenia 1 i numer poboczny 9.
Generator liczb losowych zbiera szum środowiskowy ze sterowników urządzeń i innych źródeł do puli losowej (puli entropii). Generator przechowuje również szacunkową liczbę bitów szumu w puli losowej. Z puli tej tworzone są liczby losowe.
Linux 3.17 i późniejsze zapewnia prostszy i bezpieczniejszy interfejs getrandom(2), który nie wymaga plików specjalnych; więcej informacji w podręczniku getrandom(2).
Przy odczycie, urzadzenie /dev/urandom zwraca losowe bajty, wygenerowane za pomocą pseudolosowego generatora liczb, który pozyskuje ziarno z puli entropii. Odczyt z tego urządzenia nie blokuje się (nie dochodzi do zjawiska CPU yield), ale przy pozyskiwaniu znaczących ilości danych może wystąpić znaczące opóźnienie.
Podczas odczytu we wczesnej fazie rozruchu, /dev/urandom może zwrócić dane jeszcze przed zainicjowaniem puli losowej. Zastosowanie getrandom(2) lub /dev/random nie będzie podatne na to niekorzystne zjawisko.
Urządzenie /dev/random jest przestarzałym interfejsem, pochodzącym jeszcze z czasów, gdy implementacja kryptograficznych funkcji pierwotnych (ang. cryptographic primitives) użyta w implementacji /dev/urandom nie była uważana za zaufaną. Zwraca losowe bajty w miarę napływu świeżego szumu do puli losowej i blokuje się, gdy jest to konieczne. Urządzenie /dev/random jest odpowiednie do aplikacji wymagających losowości wysokiej jakości, które mogą sobie pozwolić na opóźnienia o nieznanej długości.
When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered. Since Linux 5.6, the O_NONBLOCK flag is ignored as /dev/random will no longer block except during early boot process. In earlier versions, if open(2) is called for /dev/random with the O_NONBLOCK flag, a subsequent read(2) will not block if the requested number of bytes is not available. Instead, the available bytes are returned. If no byte is available, read(2) will return -1 and errno will be set to EAGAIN.
Flaga O_NONBLOCK nie ma znaczenia przy otwieraniu /dev/urandom. Podczas wywołania read(2) do urządzenia /dev/urandom, odczyt do 256 bajtów zwróci żądaną wielkość bajtów; nie można ich przerwać sygnałem. Odczyt przy użyciu bufora ponad ten limit może zwrócić mniejszą liczbę bajtów niż żądana lub nie powieść się z błędem EINTR, jeśli nastąpi przerwanie sygnałem.
Since Linux 3.16, a read(2) from /dev/urandom will return at most 32 MB. A read(2) from /dev/random will return at most 512 bytes (340 bytes before Linux 2.6.12).
Pisanie do /dev/random lub /dev/urandom zaktualizuje pulę entropii za pomocą pisanych danych, lecz nie zwiększy poziomu entropii. Oznacza to, że będzie to miało wpływ na odczyt z obu plików, lecz nie uczyni odczytu z /dev/random szybszym.

Użycie

Urządzenie /dev/random jest uważane za przestarzały interfejs, a /dev/urandom jest preferowany i wystarczający we wszystkich przypadkach, z wyjątkiem aplikacji wymagających losowości we wczesnej fazie rozruchu, które muszą korzystać z getrandom(2), blokującego się do czasu zainicjowania puli losowej.
Jeśli plik puli losowej jest przechowywany pomiędzy ponownymi uruchomieniami, zgodnie z poniższymi zaleceniami, wyjście jest kryptograficznie bezpieczne w stosunku do atakujących bez dostępu do lokalnego roota, zaraz po przeładowaniu go w sekwencji rozruchowej i odnosi się w całości do sieciowych kluczy szyfrujących sesji (wszystkie główne dystrybucje Linuksa zachowują plik puli losowej pomiędzy rozruchami od co najmniej 2000 roku). Ponieważ odczyt z /dev/random może nie być płynny, użytkownicy będą go z reguły chcieli otworzyć w trybie nieblokującym (lub przeprowadzać odczyt z czasem oczekiwania) i udostępniać jakiś typ powiadomienia dla użytkownika, jeśli oczekiwana losowość nie jest od razu dostępna.

Konfiguracja

Jeśli w systemie nie ma plików /dev/random i /dev/urandom, można je utworzyć przy użyciu następujących poleceń:

mknod -m 666 /dev/random c 1 8
mknod -m 666 /dev/urandom c 1 9
chown root:root /dev/random /dev/urandom

Gdy Linux uruchamiany jest przy niewielkim udziale operatora, pula losowa może być w dość przewidywalnym stanie. Faktyczna ilość szumu w puli losowej jest wówczas poniżej ilości szacowanej. Aby przeciwdziałać temu efektowi, pomocne jest zapamiętywanie informacji o puli losowej pomiędzy kolejnymi uruchomieniami systemu. Aby działo się to automatycznie, należy dodać wiersze do stosownych skryptów startowych Linuksa:

echo "Inicjowanie generatora liczb losowych..."
random_seed=/var/run/random-seed
# Przechowanie wartości losowej od jednego startu systemu
# do kolejnego startu. Ładowanie oraz późniejsze zachowywanie
# całej puli losowej.
if [ -f $random_seed ]; then
    cat $random_seed >/dev/urandom
else
    touch $random_seed
fi
chmod 600 $random_seed
poolfile=/proc/sys/kernel/random/poolsize
[ -r $poolfile ] && bits=$(cat $poolfile) || bits=4096
bytes=$(expr $bits / 8)
dd if=/dev/urandom of=$random_seed count=1 bs=$bytes

Trzeba również dodać następujące wiersze do stosownego skryptu uruchamianego podczas zamykania systemu Linuksa:

# Przechowanie losowych danych pomiędzy wyłączeniem a włączeniem
# komputera. Zachowywanie puli losowej generatora.
echo "Zachowywanie puli losowej..."
random_seed=/var/run/random-seed
touch $random_seed
chmod 600 $random_seed
poolfile=/proc/sys/kernel/random/poolsize
[ -r $poolfile ] && bits=$(cat $poolfile) || bits=4096
bytes=$(expr $bits / 8)
dd if=/dev/urandom of=$random_seed count=1 bs=$bytes

W powyższych przykładach zakładamy, że Linux jest w wersji 2.6.0 lub nowszej, gdzie /proc/sys/kernel/random/poolsize zwraca rozmiar puli entropii w bitach (zob. niżej).

Interfejsy /proc

The files in the directory /proc/sys/kernel/random (present since Linux 2.3.16) provide additional information about the /dev/random device:
entropy_avail
Plik z prawami tylko do odczytu, dostarcza dostępną entropię, w bitach. Będzie to wielkość w zakresie od 0 do 4096.
poolsize
Plik zawiera rozmiar puli losowej. Format tego pliku zależy od wersji jądra:
Linux 2.4:
Plik podaje rozmiar puli losowej w bajtach. Zazwyczaj - 512 (bajtów). Plik jest zapisywalny i może być zmieniony na dowolną wartość, dla której dostępny jest algorytm. Obecnie możliwe wartości to: 32, 64, 128, 256, 512, 1024 lub 2048.
Linux 2.6 i późniejsze:
Plik jest dostępny tylko do odczytu i podaje rozmiar puli losowej w bitach. Zawiera wartość 4096.
read_wakeup_threshold
Plik zawiera liczbę bitów entropii wymaganej do obudzenia procesu, który zasnął w oczekiwaniu na entropię z urządzenia /dev/random. Domyślna wartość do 64.
write_wakeup_threshold
Plik zawiera liczbę bitów entropii poniżej której zostanie uśpiony proces, który wykona select(2) lub poll(2), aby otworzyć do zapisu urządzenie /dev/random. Wartości te mogą być zmienione przez zapis do tych plików.
uuid i boot_id
Pliki te zawierają losowe łańcuchy znaków, takie jak 6fd5a44b-35f4-4ad4-a9b9-6b9be13e1fe9. Pierwszy z tych plików jest generowany na nowo przy każdym odczycie, a drugi jest generowany tylko raz.

Interfejs_ioctl(2)">Interfejs_ioctl(2)">Interfejs ioctl(2)

Następujące żądania ioctl(2) są zdefiniowane na deskryptorach plików połączonych z /dev/random lub /dev/urandom. Wszystkie przeprowadzone żądania wpływają na wejściową pulę entropii zarówno /dev/random jak i /dev/urandom. Możliwość CAP_SYS_ADMIN jest wymagana przez wszystkie żądania za wyjątkiem RNDGETENTCNT.
RNDGETENTCNT
Zbiera wartość entropii z puli wejściowej, zawartość będzie taka sama jak pliku entropy_avail w katalogu proc. Wyniki zostaną przechowane w liczbie całkowitej wskazanej przez argument.
RNDADDTOENTCNT
Zwiększa lub zmniejsza wartość entropii z puli wejściowej o wartość wskazaną przez argument.
RNDGETPOOL
Usunięte w Linuksie 2.6.9
RNDADDENTROPY
Dodaje dodatkową entropię do puli wejściowej, zwiększając wartość entropii. Różni się to od zapisu do /dev/random lub /dev/urandom, które dodaje pewne dane, lecz nie zwiększa wartości entropii. Używana jest poniższa struktura:

struct rand_pool_info {
    int    wartość_entropii;
    int    wiel_buf;
    __u32  buf[0];
};
    

Wartość_entropii to wartość dodawana (lub odejmowana) od wartości losowej, buf to bufor o wielkości wiel_buf dodawany do puli losowej.
RNDZAPENTCNT, RNDCLEARPOOL
Zeruje wielkość entropii we wszystkich pulach i dodaje do nich pewne dane systemowe (np. rzeczywisty czas trwania - tzw. wall clock).

PLIKI

/dev/random
 
/dev/urandom

UWAGI

Przegląd i porównanie różnych interfejsów do pozyskiwania losowości znajduje się w podręczniku random(7).

BŁĘDY

Podczas wczesnej fazy rozruchu, /dev/urandom może zwrócić dane jeszcze przed zainicjowaniem puli losowej.

ZOBACZ TAKŻE

mknod(1), getrandom(2), random(7)
RFC 1750, "Randomness Recommendations for Security"

TŁUMACZENIE

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Paweł Olszewski <[email protected]>, Robert Luberda <[email protected]> i Michał Kułach <[email protected]>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej [email protected]

Recommended readings

Pages related to random you should read also: