Scroll to navigation

RANDOM(4) Podręcznik programisty Linuksa RANDOM(4)

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.

Jeśli pula losowa jest pusta, odczyt z /dev/random będzie wstrzymany do czasu zebrania dodatkowego szumu środowiskowego. Jeśli open(2) jest wywołane do /dev/random z flagą O_NONBLOCK, kolejne read(2) nie będzie blokowane, jeśli żądana liczba bajtów nie jest dostępna. W zamian zwracane są dostępne bajty. Jeśli nie ma dostępnych bajtów, read(2) zwróci -1, a errno ustawi się na 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.

Od Linuksa 3.16, read(2) z /dev/urandom zwróci co najwyżej 32 MB. read(2) z /dev/random zwróci nie więcej niż 512 bajtów (przed jądrami Linux w wersji 2.6.12 - 340 bajtów).

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

Pliki w katalogu /proc/sys/kernel/random (obecnym od wersji 2.3.16) udostępniają dodatkowe informacje o urządzeniu /dev/random:

Plik z prawami tylko do odczytu, dostarcza dostępną entropię, w bitach. Będzie to wielkość w zakresie od 0 do 4096.
Plik zawiera rozmiar puli losowej. Format tego pliku zależy od wersji jądra:
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.
Plik jest dostępny tylko do odczytu i podaje rozmiar puli losowej w bitach. Zawiera wartość 4096.
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.
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.
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)

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.

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.
Zwiększa lub zmniejsza wartość entropii z puli wejściowej o wartość wskazaną przez argument.
Usunięte w Linuksie 2.6.9
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.
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"

O STRONIE

Angielska wersja tej strony pochodzi z wydania 5.10 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.

TŁUMACZENIE

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Paweł Olszewski <alder@amg.net.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>

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 manpages-pl-list@lists.sourceforge.net.

15 września 2017 r. Linux