2014-02-12 14 views
7

Viele CSPRNG-Benutzerbereiche haben ein Problem, bei dem es nach fork(2) möglich ist, dass die zwei verschiedenen Prozesse denselben Strom zufälliger Bytes zurückgeben.Ist SecRandomCopyBytes von OS X sicher?

Aus bei dtruss suchen, ist es klar, dass SecRandomCopyBytes ist, auf ein Minimum, Säen von /dev/random, aber es ist so in einer Art und Weise zu tun, die für den Einsatz nach fork() sicher ist?

Mit dem folgenden Quelltext:

#include <Security/Security.h> 


int main() { 
    uint8_t data[8]; 
    SecRandomCopyBytes(kSecRandomDefault, 8, data); 
    SecRandomCopyBytes(kSecRandomDefault, 8, data); 
    printf("%llu\n", *(uint64_t *)data); 
} 

ich folgendes von dtruss bekommen (mit irrelevanten Sachen entfernt):

open("/dev/random\0", 0x0, 0x7FFF900D76F5)  = 3 0 
read(0x3, "\b\2029a6\020+\254\356\256\017\3171\222\376T\300\212\017\213\002\034w\3608\203-\214\373\244\177K\177Y\371\033\243Y\020\030*M\3264\265\027\216r\220\002\361\006\262\326\234\336\357F\035\036o\306\216\227\0", 0x40)  = 64 0 
read(0x3, "\223??3\263\324\3604\314:+\362c\311\274\326\a_Ga\331\261\022\023\265C\na\211]\356)\0", 0x20)  = 32 0 

Antwort

5

Die Implementierung ist eigentlich CCRandomCopyBytes():

http://www.opensource.apple.com/source/Security/Security-55471/libsecurity_keychain/lib/SecRandom.c

int SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) { 
    if (rnd != kSecRandomDefault) 
     return errSecParam; 
    return CCRandomCopyBytes(kCCRandomDefault, bytes, count); 
} 

Also der eigentliche Code ist hier:

http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-60049/lib/CommonRandom.c

Die Kommentare im Include für CCRandomCopyBytes angeben, dass es fork() ist sicher:

Es ist unbequem System Zufallszahlengeneratoren nennen direkt. Im einfachen Fall des Aufrufs von/dev/random muss der Anrufer das Gerät öffnen und es schließen, während es geöffnet ist, und verwalten. Dieses Modul hat seine unmittelbare Daseinsberechtigung die Unannehmlichkeiten dies zu tun. Es verwaltet einen Dateideskriptor zu /dev/random einschließlich der Ausnahme Verarbeitung, was passiert in einem fork() und exec(). Call CCRandomCopyBytes() und alle Fiddly-Bits werden für Sie verwaltet. Mach einfach weiter mit dem, was du gerade anstellst . [...]

In meinem kurzen Test, wird das Kind getötet, als es SecRandomCopyBytes() aufruft