RANDOM(4)

NOME
random, urandom - dispositivi kernel che producono numeri casuali

SINTASSI
#include <linux/random.h>

int ioctl(fd, RNDrequest, param);

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

Quando viene letto, il dispositivo /dev/random restituisce solo un numero di byte casuali compatibili con la stima dei bit di rumore nella fonte di entropia. /dev/random dovrebbe essere adatto ad usi che richiedono un alto grado di casualità, come la cifratura "one-time pad" e la generazione di chiavi. 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.

La lettura del dispositivo /dev/urandom non bloccherà l'attesa di ulteriore entropia. Se non c'è sufficiente entropia, viene usato un generatore di numeri pseudocasuali per creare i byte richiesti. Di conseguenza, se non c'è abbastanza entropia nella fonte di entropia, i valori restituiti sono teoricamente vulnerabili ad un attacco crittografico sull'algoritmo usato dal driver. Nella letteratura attualmente non classificata non c'è prova di un metodo per fare ciò, ma è in teoria possibile che un attacco del genere possa esistere. Se questo è fonte di problemi per la propria applicazione, si usi invece /dev/random. O_NONBLOCK non ha nessun effetto quando si apre /dev/urandom. Quando si chiama read(2) per il device /dev/urandom, i segnali non verranno gestiti fino a dopo che i byte casuali richiesti non sono stati generati. 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.

  Uso
Se non si è sicuri di quale programma usare, /dev/random o /dev/urandom, probabilmente la scelta migliore è l'ultimo. Come regola generale, si dovrebbe usare per tutto /dev/urandom, fatta eccezione per chiavi GPG/SSL/SSH esistenti da molto tempo. Se si salva un file seed ai riavvii, come si raccomanda più avanti (tutte le più importanti distribuzioni Linux lo fanno almeno dal 2000), 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. 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. Il generatore di numeri casuali del kernel è stato sviluppato per produrre un piccolo quantitativo di materiale di seed di alta qualità, necessario a creare un generatore di numeri pseudo-casuali crittografico (CPRNG). È stato creato per essere sicuro, non per essere veloce, e non è adatto a generare grandi quantità di dati casuali. Gli utenti dovrebbero creare una piccola quantità di materiale di seed da leggere da /dev/urandom (e /dev/random): leggere grandi quantitativi di dati da questi dispositivi avrà un impatto negativo sugli altri utenti dei dispositivi. La quantità di materiale di seed richiesto per generare una chiave crittografica è uguale alla dimensione reale della chiave. Per esempio, una chiave privata RSA a 3072 bit o una Diffie-Hellmann ha una dimensione effettiva di 128 bit (e richiede circa 2^128 operazioni per essere forzata), quindi un generatore di chiavi avrà bisogno solo di 128 bit (16 byte) di materiale di seed da /dev/random. Benché sia ragionevole avere margini di sicurezza superiori a questo minimo come protezione contro le imperfezioni dell'algoritmo CPRNG, nessuna delle primitive crittografiche oggi esistente può garantire più di 256 bit di sicurezza; quindi se un programma legge più di 256 bit (32 byte) dalla fonte di casualità del kernel per ogni chiamata, o per ogni intervallo ragionevole di seed (non meno di un minuto), vuol dire che la crittografia di quel programma non è stata abilmente implementata.

  Configurazione
Se il sistema non comprende già /dev/random né /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
    # Porta il seme casuale da un avvio al successivo
    # Carica e successivamente salva l'intera fonte di entropia
    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).

  Interfaccia /proc
I file nella directory /proc/sys/kernel/random (presente da 2.3.16) forniscono un'interfaccia aggiuntiva al dispositivo /dev/random.

Il file in sola lettura entropy_avail fornisce l'entropia disponibile. Normalmente questo sarà 4096 (bit), una fonte di entropia piena.

Il file poolsize 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:
        Questo file è di sola lettura, e indica la dimensione della fonte di entropia in bit. Contiene il valore 4096.

Il file read_wakeup_threshold 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. Il file write_wakeup_threshold contiene il numero di bit di entropia sotto i quali vengono svegliati i processi che eseguono un select() o poll() per accedere in scrittura a /dev/random. Questi valori possono venire cambiati scrivendo sui file.

I file in sola lettura uuid e boot_id contengono stringhe casuali come 6fd5a44b-35f4-4ad4-a9b9-6b9be13e1fe9. Il più vecchio è generato di nuovo a ciascuna lettura, l'ultimo viene generato una volta.

  Interfaccia ioctl(2)
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.

FILE
/dev/random
/dev/urandom

VEDERE ANCHE
mknod(1), getrandom(2) RFC 1750, "Randomness Recommendations for Security"

COLOPHON
Questa pagina fa parte del rilascio 4.08 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 versione italiana fa parte del pacchetto man-pages-it v. 4.08, a cura di: ILDP "Italian Linux Documentation Project" http://www.pluto.it/ildp
Per la traduzione in italiano si può fare riferimento a http://www.pluto.it/ildp/collaborare/
Segnalare eventuali errori di traduzione a ildp@pluto.it