2014-02-12 19 views
7

許多用戶空間CSPRNG在fork(2)之後有一個問題,兩個不同進程可能返回相同的隨機字節流。OS X的SecRandomCopyBytes叉是否安全?

通過觀察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說明它是fork()的安全:

不方便調用系統中的隨機數發生器直接使用 。在調用/ dev/random的簡單情況下,調用者 必須打開設備並關閉設備,並在打開設備時對它進行管理 。這個模塊具有直接存在的問題 這樣做的不便。它管理一個文件描述符爲 /dev/random,包括在fork()和exec()中發生的異常處理 。調用CCRandomCopyBytes()和所有的位都是爲你管理的。只要與 真正想要做的事情相處即可。 [...]

在我自己的快速測試,孩子被當調用SecRandomCopyBytes()

喪生