2014-02-12 7 views
7

У многих пользователей CSPRNG есть проблема, где после fork(2) возможно, что два разных процесса возвратят один и тот же поток случайных байтов.Является ли OS X SecRandomCopyBytes fork безопасным?

Глядя на dtruss, стало ясно, что SecRandomCopyBytes есть, как минимум, посев из /dev/random, но он делает это таким образом, что это безопасно для использования после fork()?

Со следующим исходным кодом:

#include <Security/Security.h> 


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

я получаю от dtruss (с неуместным вещи удалены):

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 

ответ

5

Реализация на самом деле 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); 
} 

Так фактический код здесь:

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

Комментарии в включаемые для CCRandomCopyBytes утверждают, что вилка() сейф:

Это неудобно называть системные генераторы случайных чисел напрямую. В простом случае вызова/dev/random вызывающий абонент должен открыть устройство и закрыть его в дополнение к управлению его , пока он открыт. У этого модуля есть своя непосредственная цель: неудобство этого. Он управляет файловым дескриптором до /dev/random, включая обработку исключений из в fork() и exec(). Вызовите CCRandomCopyBytes() и все удаленные биты для вас. Просто продолжайте с того, что вы действительно делали . [...]

В моей быстрой проверки, ребенок погибает, когда он вызывает SecRandomCopyBytes()