RANDOM(4) Manuale del programmatore di Linux RANDOM(4)

random, urandom - dispositivi kernel che producono numeri casuali

#include <linux/random.h>

int ioctl(fd, RNDrequest, param);

I file speciali a caratteri /dev/random e /dev/urandom (presenti a partire da Linux 1.3.30) forniscono un'interfaccia al generatore del kernel di numeri casuali. Il file dev/random ha numero primario 1 e numero secondario 8. Il file /dev/urandom ha numero primario 1 e numero secondario 9.

Il generatore di numeri casuali raccoglie rumore di fondo dai dispositivi dei driver e da altre sorgenti nella fonte di entropia. Il generatore mantiene anche una stima del numero di bit di rumore nella fonte di entropia. Da questa fonte di entropia vengono creati i numeri casuali.

Linux 3.17 e successivi forniscono la più semplice e sicura interfaccia getrandom(2) che non richiede nessun file speciale; si veda la pagina di manuale di getrandom(2) per i dettagli.

Quando viene letto, il dispositivo /dev/urandom restituisce un numero di byte casuali prodotto da un generatore di numeri pseudocasuali inizializzato tramite la fonte di entropia. Le letture da questo dispositivo non sono bloccanti (cioè, la CPU non viene impegnata/risponde immediatamente), ma si può avere un ritardo apprezzabile qualora vengano richieste grandi quantità di dati.

Quando viene letto durante la fase di inizializzazione del sistema /dev/urandom può restituire dati prima che sia disponibile la fonte di entropia. Se questo è fonte di problemi per la propria applicazione, si usi invece getrandom(2) o /dev/random.

Il dispositivo /dev/random è un'interfaccia disponibile già da molto tempo, risalente a quando le primitive crittografiche usate nell'implementazione di /dev/urandom non erano generalmente ritenute sicure. Esso restituisce solo un numero di byte casuali prendendoli dal numero stimato di bit di rumore recente fornito dalla fonte di entropia, tenendo in attesa il chiamante se necessario. /dev/random è adatto ad usi che richiedono un alto grado di casualità, e può implicare ritardi indeterminati.

Quando la fonte di entropia è vuota, le letture di /dev/random vengono bloccate finché non viene raccolto abbastanza rumore ambientale. Se open(2) è chiamato da /dev/random col flag O_NONBLOCK, una successiva lettura di read(2) non verrà bloccata se il numero di byte richiesti non è disponibile. Vengono invece restituiti i byte disponibili. Se nessun byte è disponibile, read(2) restituirà -1 e errno verrà impostato a EAGAIN.

Il flag O_NONBLOCK non ha nessun effetto quando si apre /dev/urandom. Quando si chiama read(2) per il dispositivo /dev/urandom, letture fino a 256 byte retituiranno tanti byte quanti ne vengono richiesti e non verranno interrotti da un gestore di segnali. Letture con un buffer oltre questo limite possono restituire un numero di byte minore di quello richiesto o fallire con l'errore EINTR, se interrotto da un gestore di segnali.

Da Linux 3.16, una chiamata read(2) da /dev/urandom restituirà al massimo 32 MB. Una chiamata read(2) da /dev/random restituirà al massimo 512 byte (340 byte sui kernel Linux antecedenti alla versione 2.6.12).

La scrittura su /dev/random o /dev/urandom aggiorna la fonte d'entropia con i dati scritti, ma ciò non si tradurrà in un numero di entropia più alto. Ciò vuo dire che esso influirà sui contenuti letti da entrambi i file, ma non farà letture da /dev/random più velocemente.

L'interfaccia /dev/random è considerata un'interfaccia da mantenere per compatibilità col passato, mentre /dev/urandom è preferito e sufficiente in tutti i casi d'uso, fatta eccezione per applicazioni che richiedono casualità durante la fase di inizializzazione del sistema; per queste applicazioni si deve usare invece getrandom(2), che non risponderà all'applicazione fino a quando la fonte di entropia non viene inizializzata.

Se si salva un file seed ai riavvii, come si raccomanda più avanti, l'output sarà crittograficamente al sicuro dagli attaccanti senza accesso di root in locale dato che viene ricaricato nella sequenza di boot, e sarà perfettamente adeguato alle chiavi criptate per le sessioni di rete. (Tutte le più importanti distribuzioni Linux hanno salvato il file seed ai riavvii almeno dal 2000.) Dato che le letture da /dev/random possono bloccarsi, gli utenti solitamente vorranno aprirlo in modo non bloccante (o eseguire una lettura senza timeout), e fornire un qualche tipo di notifica se l'entropia desiderata non è immediatamente disponibile.

Se il sistema non comprende già /dev/random/dev/urandom, li si può creare coi seguenti comandi:


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

Quando un sistema Linux viene avviato senza molta interazione da parte di un utente, la fonte di entropia potrebbe essere in una condizione tutto sommato prevedibile. Questo porta a sovrastimare la quantità di rumore realmente presente nella fonte di entropia. Per contrastare questo effetto, può aiutare riportare le informazioni nella fonte di entropia fra un arresto e un riavvio. Per farlo, si aggiungano le righe ad uno script appropriato che venga eseguito durante le procedure di avvio di un sistema Linux:


echo "Inizializzazione del generatore di numeri casuali..."
random_seed=/var/run/random-seed
# Carry a random seed from start-up to start-up
# Load and then save the whole entropy pool
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

Inoltre, si aggiungano le righe seguenti ad uno script appropriato da eseguire durante le procedure di arresto di un sistema Linux:


# Riporta un seme casuale dall'arresto al riavvio.
# Salva l'intera fonte di entropia
echo "Salvataggio del seme casuale..."
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

Negli esempi visti prima, si presuppone che la versione di Linux sia la 2.6.0 o successiva, dove /proc/sys/kernel/random/poolsize restituisce la dimensione della fonte di entropia in bit (si veda più avanti).

I file nella directory /proc/sys/kernel/random (presente da 2.3.16) forniscono informazioni aggiuntive aldispositivo /dev/random:
entropy_avail
Questo file di sola lettura fornisce l'entropia disponibile, in bit. Questo sarà un numero nell'intervallo da 0 a 4096.
poolsize
Questo file fornisce la dimensione della fonte di entropia. La semantica di questo file è diversa a seconda della versione del kernel:
Linux 2.4:
Questo file indica la dimensione della fonte di entropia in byte. Normalmente questo file ha valore 512, ma è scrivibile e può essere cambiato in qualunque valore per il quale sia disponibile un algoritmo. Le scelte sono: 32, 64, 128, 256, 512, 1024 o 2048.
Linux 2.6 e successivo:
Questo file è di sola lettura, e indica la dimensione della fonte di entropia in bit. Contiene il valore 4096.
read_wakeup_threshold
Questo file contiene il numero di bit di entropia richiesti per svegliare i processi che dormono in attesa dell'entropia da /dev/random. Il valore predefinito è 64.
write_wakeup_threshold
Questo file contiene il numero di bit di entropia sotto i quali vengono svegliati i processi che eseguono un select(2) o poll(2) per accedere in scrittura a /dev/random. Questi valori possono venire cambiati scrivendo sui file.
uuid e boot_id
Questi file di sola lettura contengono stringhe casuali come 6fd5a44b-35f4-4ad4-a9b9-6b9be13e1fe9. Il più vecchio è generato di nuovo a ciascuna lettura, l'ultimo viene generato una volta.

Le seguenti richieste ioctl(2) sono definite su descrittori di file connessi o a /dev/random o a /dev/urandom. Tutte le richieste effettuate interagiscono con la fonte di entropia di input incidendo sia su /dev/random che su /dev/urandom. La capacità CAP_SYS_ADMIN è necessaria per tutte le richieste eccetto che per RNDGETENTCNT.
RNDGETENTCNT
Recupera il conteggio di entropia della fonte di input, il contenuto sarà lo stesso del file entropy_avail sotto proc. Il risultato verrà memorizzato nell'int indicato dall'argomento.
RNDADDTOENTCNT
Incrementa o decrementa il numero di entropia della fonte di input del valore indicato dall'argomento.
RNDGETPOOL
Rimosso in Linux 2.6.9.
RNDADDENTROPY
Aggiunge ulterire entropia alla fonte di input, incrementando il numero di entropia. Questo differisce dallo scrivere su /dev/random o /dev/urandom, che aggiunge solo qualche dato ma non incrementa il numero di entropia. Viene usata la seguente struttura:

struct rand_pool_info {
    int    entropy_count;
    int    buf_size;
    __u32  buf[0];
};


Dove entropy_count è il valore aggiunto (o sottratto) al numero di entropia, e buf è il buffer di dimensione buf_size che viene aggiunto alla fonte di entropia.
RNDZAPENTCNT, RNDCLEARPOOL
Azzera il conteggio di entropia di tutte le fonti e aggiunge alcuni dati di sistema (come il minutaggio) alle fonti.

/dev/random
/dev/urandom

Per una panoramica e un confronto fra le varie interfacce che possono essere usate per ottenere casualità, si veda random(7).

Durante la fase di inizializzazione del sistema, le letture da /dev/urandom possono restituire dati prima che la fonte di entropia venga inizializzata.

mknod(1), getrandom(2), random(7)

RFC 1750, "Randomness Recommendations for Security"

Questa pagina fa parte del rilascio 5.10 del progetto Linux man-pages. Una descrizione del progetto, le istruzioni per la segnalazione degli errori, e l'ultima versione di questa pagina si trovano su https://www.kernel.org/doc/man-pages/.

La traduzione italiana di questa pagina di manuale è stata creata da Ottavio G. Rizzo <rizzo@pluto.linux.it>, Giulio Daprelà <giulio@pluto.it>, Elisabetta Galli <lab@kkk.it> e Marco Curreli <marcocurreli@tiscali.it>

Questa traduzione è documentazione libera; leggere la GNU General Public License Versione 3 o successiva per le condizioni di copyright. Non ci assumiamo alcuna responsabilità.

Per segnalare errori nella traduzione di questa pagina di manuale inviare un messaggio a pluto-ildp@lists.pluto.it.

15 settembre 2017 Linux