Come è noto, /dev/random, un generatore di numeri pseudocasuali crittograficamente sicuro (CSPRNG), presenta un problema sgradevole: i blocchi. Questo articolo descrive come è possibile risolverlo.
Negli ultimi mesi, i mezzi di generazione dei numeri casuali nel kernel sono stati leggermente rielaborati, ma i problemi in questo sotto-sistema sono stati affrontati per un periodo più ampio. Le ultime sono state apportate per prevenire il blocco prolungato della chiamata di sistema getrandom() durante il caricamento del sistema, ma la causa sottostante era il comportamento del pool casuale bloccante. Una recente patch ha rimosso questo pool, e ci si aspettava che fosse integrato nel kernel principale.
Andy Lutomirski ha pubblicato la terza versione della patch a fine dicembre. Essa apporta «due principali cambiamenti semantici nelle API casuali di Linux».La patch introduce un nuovo flag GRND_INSECURE alla chiamata di sistema getrandom() (anche se Lutomirski lo chiama getentropy(), che è implementato in glibc tramite getrandom() con flag fissi); questo flag costringe la chiamata a restituire sempre la quantità di dati richiesta, ma senza garanzia che tali dati siano casuali. Il kernel si impegnerà solo a fornire i migliori dati casuali disponibili in quel momento. «Probabilmente, la cosa migliore da fare è chiamarlo 'INSECURE' (non sicuro), per scoraggiare l'uso di questa API per cose che necessitano di sicurezza».
Le patch rimuovono anche il pool bloccante. Attualmente, il kernel supporta due pool di dati casuali, uno dei quali corrisponde a /dev/random e l'altro a /dev/urandom, come descritto in questo documento del 2015. Il pool bloccante è un pool per /dev/random; la lettura di questo dispositivo sarà bloccata (come suggerisce il suo nome) fino a quando non sarà stata raccolta «sufficiente» entropia dal sistema per soddisfare la richiesta. Ulteriori letture da questo file vengono anch'esse bloccate se non c'è sufficiente entropia nel pool.
La rimozione del pool di blocco significa che la lettura da /dev/random si comporta come getrandom() con il flag settato a zero (e trasforma il flag GRND_RANDOM in noop). Dopo l'inizializzazione del generatore di numeri casuali crittografico (CRNG), la lettura da /dev/random e le chiamate a getrandom(…,0) non causeranno blocchi e restituiranno la quantità richiesta di dati casuali.
Lutomirski dice: «Ritengo che il pool bloccante di Linux sia obsoleto. Il CRNG di Linux genera un output che è sufficientemente buono da essere utilizzato anche per la generazione di chiavi. Il pool bloccante non è più forte in alcun modo e richiede molte infrastrutture di dubbio valore per essere mantenuto».
Le modifiche sono state apportate con l'intenzione di garantire che i programmi esistenti non subissero danni e, in effetti, ci saranno meno problemi con l'attesa prolungata per cose come la generazione di chiavi GnuPG.
«Queste modifiche non dovrebbero interrompere alcun programma esistente. /dev/urandom rimane invariato. /dev/random è ancora bloccato subito dopo il caricamento, ma ora è meno bloccato di prima. getentropy() con i flag esistenti restituirà un risultato che sarà altrettanto valido per scopi pratici come prima».
Lutomirski ha notato che rimane aperta la questione se il kernel debba fornire quelli che vengono definiti «numeri casuali veri», che in un certo senso era precisamente il compito del kernel bloccante. Vede solo una motivazione per questo: «il rispetto degli standard governativi». Lutomirski ha suggerito che, se il kernel deve fornirlo, dovrebbe farlo tramite un'interfaccia completamente diversa o trasferito nello spazio utente, permettendo a quest'ultimo di estrarre campioni grezzi di eventi che possono essere utilizzati per creare un pool di blocco.
Stephan Müller ha suggerito che il suo set per il generatore di numeri casuali Linux (LRNG) (attualmente alla versione 26) potrebbe essere un modo per fornire numeri casuali veri per le applicazioni che ne hanno bisogno. LRNG «è completamente conforme ai requisiti delle 'Raccomandazioni sulle fonti di entropia utilizzate per la generazione di bit casuali' SP800-90B», rendendolo una soluzione al problema degli standard governativi.
Matthew Garrett ha contestato il termine «dati davvero casuali», osservando che i dispositivi selezionati possono essere in linea di principio modellati con sufficiente precisione per renderli prevedibili: «qui non stiamo campionando eventi quantistici».
Müller ha risposto che questo termine deriva dallo standard tedesco AIS 31 per descrivere un generatore di numeri casuali, che produce risultati "alla stessa velocità con cui la fonte di rumore di base genera entropia."
Oltre alle ambiguità terminologiche, la presenza di un pool bloccante, come suggerito dalle patch LRNG, porterà semplicemente a vari problemi, almeno se è accessibile senza privilegi.
Come ha detto Lutomirski: "Questo non risolve il problema. Se due utenti diversi eseguono programmi causali, come gnupg, si esauriranno a vicenda. Vedo che ci sono attualmente due problemi principali con /dev/random: è soggetto a DoS (cioè esaurimento delle risorse, attacchi dannosi o simili), e poiché non sono richiesti privilegi per utilizzarlo, è anche soggetto a usi impropri. Gnupg è errato, è un collasso totale. Se aggiungiamo una nuova interfaccia non privilegiata che verrà utilizzata da gnupg e programmi simili, perderemo di nuovo."
Müller ha osservato che l'aggiunta di getrandom() consentirà ora a GnuPG di utilizzare questa interfaccia, poiché garantirà che il pool sia stato inizializzato. Basandosi sulle discussioni con lo sviluppatore di GnuPG Werner Koch, Müller ritiene che tale garanzia sia l'unica ragione per cui GnuPG attualmente legge direttamente da /dev/random. Ma se esiste un'interfaccia non privilegiata soggetta a attacchi DoS (come attualmente /dev/random), allora, secondo Lutomirski, verrà utilizzata in modo errato da alcune applicazioni.
Theodore Yue Tak Ts’o, sviluppatore del sottosistema di numeri casuali di Linux, ha apparentemente cambiato idea riguardo alla necessità di un pool di blocco. Ha affermato che l'eliminazione di questo pool consentirà di eliminare efficacemente l'idea che Linux possieda un vero generatore di numeri casuali (TRNG): «non è un'assurdità, poiché è esattamente ciò che hanno sempre fatto *BSD».
È anche preoccupato che fornire un meccanismo TRNG servirà semplicemente come esca per gli sviluppatori applicativi e ritiene che, considerando i vari tipi di hardware supportati da Linux, sia impossibile garantire un TRNG nel kernel. Il problema non sarà risolto nemmeno dalla possibilità di funzionare solo con privilegi di root: «Gli sviluppatori di applicazioni indicano che la loro applicazione, per motivi di sicurezza, deve essere installata come root, poiché solo in questo modo è possibile accedere a 'numeri casuali realmente buoni'."
Müller ha chiesto se Ts'o avesse abbandonato l'implementazione del pool bloccante che lui stesso aveva proposto da tempo. Ts'o ha risposto che intende adottare le patch di Lutomirski e si oppone attivamente all'aggiunta di un'interfaccia bloccante nel kernel.
"Il kernel non può fornire alcuna garanzia riguardo se la source di rumore sia stata correttamente caratterizzata. L'unica cosa che può ottenere uno sviluppatore di GPG o OpenSSL è una vaga sensazione che TRUERANDOM sia 'migliore', e poiché vogliono maggiore sicurezza, sicuramente cercheranno di utilizzarlo. A un certo punto verrà bloccato, e quando qualche altro utente intelligente (forse un esperto di distribuzione) lo inserirà nello script init, e i sistemi smetteranno di funzionare, agli utenti non resterà che lamentarsi con Linus Torvalds."
Ts'o sostiene anche di fornire ai crittografi e a chi ha davvero bisogno di TRNG un modo per raccogliere la propria entropia nello spazio utente, in modo da utilizzarla a loro piacimento. Affirma che la raccolta di entropia non è un processo che può essere gestito dal kernel su tutti i vari hardware supportati, inoltre, il kernel stesso non può valutare la quantità di entropia fornita da diverse fonti.
"Il kernel non dovrebbe mescolare diverse source di rumore, e certamente non dovrebbe cercare di affermare di sapere quanti bit di entropia riceve quando cerca di giocare a qualche 'strana gioco di entropia' su architetture CPU semplici e deprimenti per i casi d'uso IOT/Embedded, quando tutto è disincronizzato con un unico generatore master, quando non ci sono istruzioni CPU per riordinare o rinominare i registri, ecc."
«È possibile parlare della fornitura di strumenti che tentano di effettuare questi calcoli, ma tali operazioni dovrebbero essere eseguite sull'hardware di ciascun utente, il che risulta impraticabile per la maggior parte degli utenti della distribuzione. Se è destinato solo ai crittografi, allora deve essere fatto nel loro spazio utente. E non semplifichiamo GPG, OpenSSL, ecc., affinché tutti possano dire: 'vogliamo 'verità casuale' e non accettiamo meno'. Possiamo discutere di come forniamo interfacce ai crittografi, affinché possano ottenere le informazioni necessarie grazie all'accesso a fonti di rumore primarie, separate e designate, e forse in qualche modo la fonte di rumore sarà in grado di autenticarsi nella libreria o nell'applicazione dello spazio utente».
Si è svolta una piccola discussione su come potrebbe apparire tale interfaccia, dato che, ad esempio, alcuni eventi potrebbero avere ripercussioni in termini di sicurezza. Cao ha sottolineato che i codici di scansione della tastiera (cioè le pressioni dei tasti) si mescolano in un pool come parte della raccolta di entropia: 'Trasferire questo nello spazio utente, anche attraverso una chiamata di sistema privilegiata, sarebbe, a dir poco, imprudente'. È del tutto possibile che anche altri tempi di eventi possano generare qualche fuga informativa attraverso canali secondari.
Così, sembra che il lungo problema del sottosistema di numeri casuali di Linux sia sulla strada per una soluzione. Le modifiche che il sottosistema di numeri casuali ha subito di recente hanno portato solo a problemi di DoS durante il suo utilizzo. Ora, però, ci sono metodi efficaci per ottenere i migliori numeri casuali che il kernel può fornire. Se TRNG è ancora desiderabile per Linux, allora questa lacuna dovrà essere affrontata in futuro, ma è probabile che ciò non avvenga all'interno del kernel stesso.
Un po' di pubblicità 🙂
Grazie per essere con noi. Ti piacciono i nostri articoli? Vuoi vedere più contenuti interessanti? Supportaci effettuando un ordine o raccomandandoci ai tuoi conoscenti, , un'alternativa unica ai server entry-level, che abbiamo creato per te: (disponibili opzioni con RAID1 e RAID10, fino a 24 core e fino a 40GB DDR4).
Dell R730xd a metà prezzo nel data center Equinix Tier IV ad Amsterdam? Solo da noi nei Paesi Bassi! Dell R420 — 2x E5-2430 2.2GHz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — a partire da $99! Scopri di più su
Fonte: habr.com
