Afhankelijk van willekeur: /dev/random vs /dev/urandom

Een aantal weken geleden werd ik gebeld met een interessante vraag: “De entropy op een productieserver wordt niet snel genoeg aangevuld, waardoor processen vertragen. Deze wachten namelijk totdat er weer voldoende entropy beschikbaar is. Is het veilig om /dev/urandom te gebruiken in plaats van /dev/random?”. Eerlijk is eerlijk, mijn eerste gedachte was: kan dit opraken dan? Ja dat kan, is eigenlijk ook heel logisch, maar ik was een dergelijk probleem nog nooit eerder tegengekomen. En daardoor was er dus ook niet eerder een aanleiding geweest om me hier wat verder in te verdiepen. De hoogste tijd dus om dat te gaan doen. 

Voor degene die bij het lezen van de eerste zin dacht “entro…wat?”, even een stapje terug. Cryptografie is de kunst van het versleutelen (encryptie) en ontsleutelen (decryptie) van informatie. De achterliggende gedachte is dat een verzender en ontvanger informatie met elkaar kunnen uitwisselen, zonder dat derden deze informatie kunnen lezen in het geval de communicatie wordt onderschept. Voor encryptie en decryptie wordt gebruik gemaakt van ciphers (cryptografische algoritmes) die op meerdere wijzen kunnen worden ingezet; de zogenaamde modes of operation. Twee bekende voorbeelden van modes of operation zijn ECB en CBC.

Willekeur is belangrijk

Nu ben ik geen crypto specialist en wil ik ook niet teveel de diepte in gaan, maar wanneer je in de onderstaande afbeelding kijkt naar het verschil tussen deze twee modi, dan valt op dat CBC start met een zogenaamde Initialization Vector (ook wel Starting Variable genoemd). Dit is een willekeurig nummer, en is van cruciaal belang voor betrouwbare cryptografie. Het zorgt er in dit voorbeeld onder andere voor dat encryptie altijd een ander resultaat oplevert, zelfs wanneer dezelfde gegevens worden versleuteld. Dit maakt de kans van slagen van cryptanalysis een stuk lager. Denk bijvoorbeeld aan een aanvaller die patronen probeert te ontdekken in de wijze waarop de cipher gegevens versleuteld, om op basis van de ontstane inzichten een onderschept bericht te kunnen ontsleutelen/kraken.

601px-ECB_encryption.svg

601px-CBC_encryption.svg

In tegenstelling tot CBC is ECB dus per definitie onveilig, omdat er geen willekeurigheid wordt toegepast. De onderstaande afbeelding geeft dit grafisch goed weer: bij gebruik van de ECB mode zijn de oorspronkelijke gegevens relatief gemakkelijk te herleiden. Bij het gebruik van andere modi (zoals bijvoorbeeld CBC) is het dit al een stuk moeilijker.

mode_of_operation_difference

Nu zijn er vast belangrijke details die ik niet heb genoemd, maar bovenstaand voorbeeld maakt mijns inziens voldoende duidelijk waarom willekeurigheid zo belangrijk is in de cryptografie. Het komt erop neer dat er vele cryptografische toepassingen zijn waar willekeurigheid nodig is voor een veilige werking. Computersystemen verzamelen daartoe continu willekeurige data en slaan dit op voor (toekomstig) gebruik. De willekeurigheid verzameld door een computersysteem wordt entropy genoemd.

Entropy

Entropy in een computersysteem wordt verzameld uit verschillende bronnen met een willekeurig karakter. Denk bijvoorbeeld aan lees- en schrijf acties op een harde schijf, toetsenbordaanslagen, muisbewegingen, enzovoorts. In een Linux systeem kan reeds verzamelde entropy worden opgevraagd door het aanspreken van de device file genaamd /dev/random. En wanneer er meer entropy wordt gebruikt dan gegenereerd, kan /dev/random inderdaad ‘opraken’. Wanneer dat gebeurt, dan zal de (cryptografische) functie die willekeurigheid wil gebruiken, wachten totdat er weer voldoende entropy beschikbaar is. En dat kan dus resulteren in een vertraagde/foutieve werking van het systeem.

Er kan in een dergelijk situatie worden uitgeweken naar een alternatief, namelijk het gebruik van de device file /dev/urandom waarbij de extra “u” staat voor unlimited. Het verschil zit hem in het feit dat /dev/urandom niet blokkeert op het moment dat de entropy op is, maar entropy gaat genereren wanneer dat gebeurt. De functie die willekeurigheid vraagt, ontvangt dus altijd een antwoord en hoeft er niet meer op te wachten.

Is /dev/urandom onveilig?

De grote vraag is echter of /dev/urandom onveiliger is als /dev/random. Er wordt namelijk vaak gesteld dat dit het geval is, omdat /dev/urandom geen zuivere willekeur zou bevatten. Op basis van een snelle internet search én een korte rondvraag in mijn netwerk, vallen me twee dingen op:

  1. Over het feit dat slechte willekeur zorgt voor onbetrouwbare encryptie, lijkt iedereen het eens te zijn. Ik heb in ieder geval niemand gesproken die dat tegenspreekt. Zie bijvoorbeeld deze blogpost van Bruce Schneijer.
  2. Over de betrouwbaarheid van /dev/urandom heerst wat meer onzekerheid. Dat komt waarschijnlijk ook doordat er vaak wordt gesproken over de “theoretisch mogelijkheid” dat /dev/urandom minder willekeurig zou zijn. Zie bijvoorbeeld de Linux man page, of het artikel op Wikipedia. Dit alleen al zorgt ervoor dat de meeste mensen het zekere voor het onzekere nemen. Dus als het even kan wordt het gebruik van /dev/urandom vermeden, al is het maar omdat men niet precies weet hoe de vork in de steel zit, of om discussies te voorkomen.

Gelukkig zijn er ook mensen die dit onderwerp verder hebben uitgediept, en stellen dat er voor wat betreft betrouwbaarheid of veiligheid, geen verschil zit tussen /dev/urandom en /dev/random. Zelf vind ik het artikel “Myths about /dev/urandom” erg goed geschreven. Thomas Hühn, de auteur van dit artikel, legt vrij gedetailleerd uit waarom hij denkt dat het gebruik van /dev/urandom in de meeste gevallen net zo veilig is dan het gebruik van /dev/random, en laat een aantal experts aan het woord die zijn zienswijze bevestigen. Ik adviseer geïnteresseerden om dit artikel eens op je gemak door te lezen, maar zijn betoog komt neer op het volgende:

  • /dev/urandom en /dev/random maken beiden gebruik maken van de kernelfunctie CSPRNG (cryptographically secure pseudorandom number generator) voor het genereren van entropy. Zie hiervoor ook de onderstaande afbeelding. Er is zit dus geen verschil in de kwaliteit van de geleverde willekeur.
  • Wanneer er onvoldoende willekeur uit de bronnen komt, kan CSPRNG op basis van een beetje “starting randomness” (seed) willekeur genereren die van vergelijkbare kwaliteit is. Thomas stelt dus dat het voor de kwaliteit van de entropy helemaal niet nodig is om continu willekeur te verzamelen uit bronnen.

random_urandom_csprng

Hierop voortbordurend betekent dit wel dat een computersysteem ervoor dient te zorgen dat er altijd voldoende “starting randomness” beschikbaar is. Is dat er niet, dan is er inderdaad een kans dat CSPRNG entropy met verminderde willekeur fabriceert. En dit kan een risico zijn, zoals bijvoorbeeld ooit het geval was bij OpenWRT. Hühn schrijft hierover:

Linux’s /dev/urandom happily gives you not-so-random numbers before the kernel even had the chance to gather entropy. When is that? At system start, booting the computer.

FreeBSD does the right thing: they don’t have the distinction between /dev/random and /dev/urandom, both are the same device. At startup /dev/random blocks once until enough starting entropy has been gathered. Then it won’t block ever again.

On Linux it isn’t too bad, because Linux distributions save some random numbers when booting up the system (but after they have gathered some entropy, since the startup script doesn’t run immediately after switching on the machine) into a seed file that is read next time the machine is booting. So you carry over the randomness from the last running of the machine.

Ook de Ptaceks stellen dat /dev/urandom beter is dan /dev/random, omdat /dev/random je software minder stabiel maakt (vanwege de wachttijd als de entropy op raakt), maar cryptografisch gezien niks toevoegt ten opzichte van /dev/urandom. Ook zij zien echter het risico wat kan optreden op het moment dat software start tijdens het opstarten van een systeem:

On Linux, if your software runs immediately at boot, and/or the OS has just been installed, your code might be in a race with the RNG. That’s bad, because if you win the race, there could be a window of time where you get predictable outputs from urandom.

Daarnaast geven de Ptaceks nog aan dat het belangrijk is dat er gebruik wordt gemaakt van de kernel CSPRNG en niet van userspace CSPRNG’s. De willekeur afkomstig van userspace CSPRNG’s is namelijk van mindere kwaliteit, en veel recente Random Number Generator kwetsbaarheden waren vaak gerelateerd aan de userspace variant.

Conclusie

Gebaseerd op het bovenstaande zie ik weinig bezwaren om het gebruik van /dev/urandom af te raden. Als je continu last hebt van een lege /dev/random, schakel dan gerust over op /dev/urandom. Enige puntje van aandacht is de behoefte aan willekeur tijdens of vlak na het opstarten van een systeem, maar ook daar zijn prima oplossingen voor te bedenken. Wat daarnaast kan helpen is het gebruiken van een nieuwe(re) kernel; deze gebruiken vaak meer bronnen voor het genereren van entropy waardoor de aanvoer van willekeur kan toenemen. Ook kun je proberen om de willekeur in /dev/random aan te vullen met een zogenaamde RNG daemon. Let er dan wel op dat deze daemon geen gebruik maakt van userspace CSPRNG, maar van kernel CSPRNG.

Tot slot is het belangrijk om de context niet uit het oog te verliezen. Niet iedereen heeft staatsgeheimen die koste wat kost beschermd dienen te worden. En als je nog niet overtuigd bent van het feit dat /dev/urandom net zo veilig is dan /dev/random, gebruik (het in jouw ogen onveilige) /dev/urandom dan alleen in situaties waarbij er een beperkte geldigheid van toepassing is. Bijvoorbeeld voor tijdelijke session keys, maar niet voor certificaten met een lange geldigheidsduur.

2 antwoorden
  1. Reinier zegt:

    Grappig dat je aangeeft niet teveel de diepte in te gaan 🙂

    Hoe past het verhaal dat Intel voor de NSA in de processor een “fout” in de RND functie heeft toegevoegd? Zit dat in CSPRNG?

    Beantwoorden
  2. Dennis Baaten
    Dennis Baaten zegt:

    Hoi Reinier,

    Leuke vraag! Hieronder mijn interpretatie van dit debacle. (ook weer zo kort mogelijk :-p)

    Er zijn verschillende implementaties van CSPRNG welke vaak zijn gebaseerd op een bepaalde standaard/specificatie. Zo is er de open source variant Yarrow die wordt gebruikt in bijvoorbeeld iOS, OS X, en FreeBSD. Er is ook een NIST publicatie die luistert naar de naam SP 800-90A. Daarin zijn de specificaties voor 4 CSPRNG’s uitgewerkt, waaronder Dual_EC_DRBG.

    Het werd onrustig in informatiebeveiligingsland toen Edward Snowden in 2013 NSA memo’s lekte waarin stond dat de NSA het zodanig had weten te regelen dat ze de enige editor van de Dual_EC_DRBG standaard waren, en een cryptografische backdoor had ingebouwd. In een reactie daarop heeft NIST in april 2014 de SP800-90A opnieuw open gesteld voor publiek commentaar, waarna de Dual_EC_DRBG standaard uit de publicatie is verwijderd.

    Processormaker Intel heeft sinds 2011 een instructie genaamd RdRand aan haar instructieset voor processoren toegevoegd. Dit is een hardwarematige RNG die gebruikt kan worden als bron van willekeur, en is gebaseerd op SP800-90A met daarin dus de vermeende crytografhische backdoor. Intel stelt echter dat het van de SP800-90A alleen de standaard CTR_DRBG gebruikt, en dus niet de gebackdoorde variant Dual_EC_DRBG. Wat er nou precies waar is weet ik ook niet, maar Intel heeft in ieder geval de schijn tegen. En het gevolg hiervan is dat het gebruik van Intels RdRand wordt afgeraden door specialisten.

    Voor de duidelijkheid. Als je de aanname doet dat de RdRand van Intel inderdaad kwetsbaar is, dan wil dat nog niet meteen zeggen dat je door het gebruik van een Intel processor ook kwetsbaar bent. Het hangt dan af van het feit of het computersysteem de hardware NRG van Intel ook gebruikt. Linus Torvalds stelt namelijk dat Linux ook andere bronnen gebruik voor het maken van entropy, en dus niet uitsluitend gebruik maakt van RdRand. Door willekeur van verschillende bronnen te mixen zou Linux niet vatbaar zijn voor de vermeende kwetsbaarheid. En voor mensen die zelf hun kernels maken: je kunt de ondersteuning voor Intel hardware RNG ook eruit laten.

    Dennis

    Beantwoorden

Plaats een Reactie

Meepraten?
Draag gerust bij!

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *