getrandom(2)

NAZWA
getrandom - pozyskuje serię losowych bajtów

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <sys/random.h>

ssize_t getrandom(void buf[.buflen], size_t buflen, unsigned int flags);

OPIS
Wywołanie systemowe getrandom() wypełnia bufor wskazywany przez buf do wielkości buflen losowych bajtów. Bajtów tych można użyć jako ziarna dla generatorów liczb losowych w przestrzeni użytkownika, do celów kryptograficznych.

Domyślnie, getrandom() pozyskuje entropię ze źródła urandom (tj. tego samego źródła, co urządzenie /dev/urandom). To zachowanie można zmienić argumentem flags.

Jeśli źródło urandom zostało zainicjowane, odczyt do 256 bajtów zawsze zwróci tak dużo bajtów, jak zażądano i nie będzie przerywany sygnałami. Gwarancji takiej nie ma dla większych buforów. Na przykład, jeśli wywołanie zostanie przerwane przez procedurę obsługi sygnału, może zwrócić częściowo wypełniony bufor lub zawieść z błędem EINTR.

Jeśli źródło urandom nie zostało zainicjowane, getrandom() zablokuje, chyba że we flags podano GRND_NONBLOCK.

Argument flags jest maską bitową, która może zawierać sumę (OR) zera lub więcej poniższych wartości:

GRND_RANDOM
    Jeśli ten bit jest ustawiony, to losowe bajty są pozyskiwane ze źródła random (tj. tego samego źródła, co urządzenie /dev/random), zamiast ze źródła urandom. Źródło random jest ograniczone, w zależności od entropii, jaka może zostać pozyskana z szumu środowiskowego. Jeśli liczba dostępnym bajtów w źródle random jest mniejsza, niż żądana w buflen, to wywołanie zwróci jedynie dostępne bajty losowe. Jeśli w ogóle brak jest dostępnych losowych bajtów, zachowanie zależy od obecności GRND_NONBLOCK w argumencie flags.

GRND_NONBLOCK
    Domyślnie, przy odczycie ze źródła random, getrandom() blokuje, gdy brak jest dostępnych losowych bajtów, a przy odczycie ze źródła urandom blokuje, gdy pula entropii nie została jeszcze zainicjowana. Jeśli ustawiony jest znacznik GRND_NONBLOCK, to getrandom() w tych przypadkach nie blokuje, lecz natychmiast zwraca -1, z errno ustawionym na EAGAIN.

WARTOŚĆ ZWRACANA
Przy powodzeniu, getrandom() zwraca liczbę bajtów skopiowanych do bufora buf. Może być ona mniejsza, niż liczba bajtów żądanych za pomocą buflen, jeśli we flags podano GRND_RANDOM i w źródle random była obecna niewystarczająca entropia, albo jeśli wywołanie systemowe zostało przerwane sygnałem.

W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

EAGAIN
    Żądana entropia nie była dostępna i getrandom() zablokowałoby, gdyby nie był ustawiony znacznik GRND_NONBLOCK.

EFAULT
    Adres, do którego odnosi się buf był poza dostępną przestrzenią adresową.

EINTR
    Wywołanie systemowe zostało przerwane procedurą obsługi sygnału; zob. opis w podręczniku signal(7), jak obsługiwane jest przerwane wywołanie read(2) na „powolnych” urządzeniach z, oraz bez, znacznika SA_RESTART.

EINVAL
    We flags podano nieprawidłowy znacznik.

ENOSYS
    Funkcja opakowująca getrandom() z glibc ustaliła, że bieżące jądro nie implementuje tego wywołania systemowego.

STANDARDY
Linux.

HISTORIA
Linux 3.17, glibc 2.25.

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

W przeciwieństwie do /dev/random i /dev/urandom, getrandom() nie angażuje ścieżek, ani deskryptorów plików. Z tego powodu getrandom() może być użyteczne w przypadkach, gdy chroot(2) czyni ścieżki /dev niewidocznymi oraz gdy aplikacja (np. demon w trakcie rozruchu) zamyka deskryptor pliku jednego z tych plików, który był otwarty przez bibliotekę.

  Maksymalna liczba zwracanych bajtów
Według stanu na Linuksa 3.19 istnieją następujące limity:

•   Przy odczycie ze źródła urandom, w systemach gdzie int ma rozmiar 32 bitów, pojedynczym wywołaniem do getrandom zwracanych jest maksymalnie 32Mi-1 bajtów.

•   Przy odczycie ze źródła random, zwracanych jest co najwyżej 512 bajtów.

  Przerwanie procedurą obsługi sygnału
Przy odczycie ze źródła urandom (nie jest ustawiony GRND_RANDOM), getrandom() zablokuje, dopóki nie zostanie zainicjowana pula entropii (chyba, że podano znacznik GRND_NONBLOCK). Jeśli żądano odczytu dużej liczby bajtów (powyżej 256), getrandom() zablokuje, dopóki bajty te nie zostaną wygenerowane i przeniesione z pamięci jądro do buf. Przy odczycie ze źródła random (jest ustawiony GRND_RANDOM), getrandom() zablokuje, dopóki jakieś losowe bajty nie staną się dostępne (chyba, że podano znacznik GRND_NONBLOCK).

Zachowanie, gdy wywołanie do zablokowanego w trakcie odczytu ze źródła urandom getrandom(), zostanie przerwane procedurą obsługi sygnału, zależy od stanu zainicjowania bufora entropii oraz od żądanego rozmiaru w buflen. Jeśli entropia nie została jeszcze zainicjowana, to wywołanie zawiedzie z błędem EINTR. Jeśli pula entropii została zainicjowana, a żądany rozmiar jest duży (buflen > 256), to wywołanie albo powiedzie się, zwracając częściowo wypełniony bufor, albo zawiedzie z błędem EINTR. Jeśli pula entropii została zainicjowana, a żądany rozmiar jest mały (buflen <= 256), to getrandom() nie zawiedzie z EINTR, lecz zwróci wszystkie żądane bajty.

Przy odczycie ze źródła random, blokujące żądania o dowolnym rozmiarze mogą być przerwane procedurą obsługi sygnału (wywołanie zawiedzie z błędem EINTR).

Preferowaną metodą korzystania z getrandom(), jest odczyt małych buforów (<= 256 bajtów) ze źródła urandom.

Specjalny sposób traktowania małych wartości buflen został zaprojektowany w celu zachowania kompatybilności z getentropy(3) z OpenBSD, które jest obecnie obsługiwane w glibc.

Użytkownik getrandom() zawsze musi sprawdzać zwracaną wartość, aby określić, czy wystąpił błąd, czy też zwrócono mniej bajtów niż żądano. W przypadku gdy nie poda się GRND_RANDOM, a buflen jest mniejsze lub równe 256, nigdy nie powinna wystąpić sytuacja zwrócenia mniejszej liczby bajtów niż żądano, lecz ostrożny programista i tak powinien to sprawdzić!

USTERKI
Według stanu na Linuksa 3.19, występuje poniższy błąd:

•   W zależności od obciążenia procesora, getrandom() nie reaguje na przerwania, przed odczytem wszystkich żądanych bajtów.

ZOBACZ TAKŻE
getentropy(3), random(4), urandom(4), random(7), signal(7)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: 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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.