getrandom(2) System Calls Manual getrandom(2)

getrandom - pozyskuje serię losowych bajtów

Standardowa biblioteka C (libc, -lc)

#include <sys/random.h>
ssize_t getrandom(void buf[.buflen], size_t buflen, unsigned int flags);

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:

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.
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.

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.

Żądana entropia nie była dostępna i getrandom() zablokowałoby, gdyby nie był ustawiony znacznik GRND_NONBLOCK.
Adres, do którego odnosi się buf był poza dostępną przestrzenią adresową.
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.
We flags podano nieprawidłowy znacznik.
Funkcja opakowująca getrandom() z glibc ustaliła, że bieżące jądro nie implementuje tego wywołania systemowego.

Linux.

Linux 3.17, glibc 2.25.

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ę.

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.

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ć!

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.

getentropy(3), random(4), urandom(4), random(7), signal(7)

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: 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.

2 maja 2024 r. Linux man-pages 6.9.1