Ne tak úplně. Vlastně vůbec ne. Od kdy je Linus uznávaný expert na kryptografii? Vždyť linuxový RNG je zbytečně složitý, a kvůli tomu má slabiny které by jednodušší konstrukce neměla: http://eprint.iacr.org/2006/086.pdf
To vylepšování je obyčejné XOR. To je OK, pokud je výsledek RDRAND náhodný se špatnou entropií, nebo třeba i konstantní. Bohužel, XOR není jednosměrná operace, takže je snadné vymyslet operand který entropii sníží, pokud známe druhý operand. A procesor ho samozřejmě zná, vždyť s ním zrovna operuje.
Pochopitelně je třeba určit, kdy se dělá XOR do paměti, a kde je uložený druhý operand. Až na to, že to není zrovna těžký problém, RDRAND není zrovna běžná instrukce, takže její zavolání jasně signalizuje že jsme v kódu RNG. API linuxového kernelu se moc nemění, a adresa bufferu bude nejspíš v nějakém registru.
Tady to hezky rozebírá nějaký Taylor Hornby: http://pastebin.com/A07q3nL3
Taky je potřeba si uvědomit, že může být velký problém tohle detekovat. RNG jsou složité, jsou dobré důvody je obfuskovat, takže analýza křemíku bude dost těžká (a nikdo se nad tím nepozastaví). Tenhle exploit může být aktivovaný jen za nějakých podmínek, a výsledek může být spočítaný tak, aby se entropie snížila jen pro někoho kdo zná heslo (třeba může existovat klíč který má NSA, a RDRAND = SHA1(interní čítač + ID procesoru + NSA_KEY) XOR (aktuální buffer s entropií)). Výsledek linuxového RNG potom bude deterministický generátor, ke kterému má NSA klíč, ale důkaz by vyžadoval umět prolomit současný kryptografický hash, takže není proveditelný.
TL;DR ve stylu Linuse: Jsi ignorant, Linusi, děláš do věcí kterým nerozumíš.
Tak jsem si otevřel random.c a myslel jsem, že budu moct tebe a Taylora setřít, že jste ignoranti, ale vypadá to, že je generátor náhodných čísel opravdu napadnutelný. Myslel jsem, že výsledné náhodné číslo vznikne nějakou složitou kryptografickou funkcí z původního čísla a rdrand, ale všechna ta složitá kryptografie probíhá už před získáním náhodného čísla z CPU a pak už dochází pouze ke XORU a kopírování zmanipulovatelného čísla do výstupu.
Takže Linusi, otevři si random.c, arch/x86/kernel/cpu/rdrand.c a /arch/x86/include/asm/archrandom.h a chvilku přemýšlej. Myslím, že by stačilo pár řádků přehodit a modifikovat (nezahazovat předchozí náhodné číslo, udělat hash současného a předchozího a až tento hash použít ke generování výsledného čísla) a výsledek by byl daleko důvěryhodnější.
Jenže všechna složitá kryptografie je k ničemu, když nakonec někdo generuje taková čísla, aby po XORu vznikla známá posloupnost. Dokážu si představit, jak sestavit procesor, aby jádro Linuxu se současným generátorem vytvářelo sekvenci např. 0, 1, 2, 3, ... Stačí aby procesor detekoval požadavek pro náhodná čísla, zkontroloval následující instrukce, našel v cache, s čím se bude provádět xor, spočítal vhodný výstup a nechal výsledek zpracovat předem známým způsobem na výrobcem požadovaný výsledek. Myslím, že se to prakticky ničím nedá detekovat, jedině podrobnou analýzou procesoru.
Musí:
1) poznalo by se to debugováním
2) mohly by vznikat chyby v programu způsobené nesprávným zápisem
Věřit nemůžeme prakticky ničemu, víme, že zadní vrátka se vyskytují poměrně často. Ale zas je zbytečné být paranoidní a myslet si, že BSA sleduje, jestli náhodou do Linuxu nestahuju MS Office a proto mi podstrčila síťovou kartu, která na mě všechno bonzuje přes router s bezpečnostní dírou pro komunikaci se serverem CIA.
Tak jsem se v tom trochu vrtal, abych treba dokazal ze nemate pravdu :D. A dopracoval jsem se k tehle asi klicove funkci :
void get_random_bytes_arch(void *buf, int nbytes)
1074 {
1075 char *p = buf;
1076
1077 trace_get_random_bytes(nbytes, _RET_IP_);
1078 while (nbytes) {
1079 unsigned long v;
1080 int chunk = min(nbytes, (int)sizeof(unsigned long));
1081
1082 if (!arch_get_random_long(&v))
1083 break;
1084
1085 memcpy(p, &v, chunk);
1086 p += chunk;
1087 nbytes -= chunk;
1088 }
1089
1090 if (nbytes)
1091 extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
Coz na prvni pohled vypada ze se z HW generovaneho RND udela jeste SHA1 (ve funkci "extract_entropy", nicmene konstrukce na radku 1090,1091 se podle mne neprovede asi nikdy. Nebo se pletu ?
Souhlasim s odkazovanym textem, sice by to nebylo tak jednoduche, ale cesta to urcite je.
Reseni by mohlo byt oddelit od sebe rdrand a to prixorovani, tedy udelat tam jakousi "frontu". Dalsi zlepseni by bylo pridani nejake nelinearity (=hodne jednoduchy algoritmus). Docela dobre by se na to mohly hodit BCD instrukce x86 kdyby je z AMD64 nevyhodili, konecne by pro ne zase bylo nejake vyuziti ;-).