OS X的SecRandomCopyBytes分支是否安全?

7
许多用户空间CSPRNG存在一个问题,即在fork(2)后,两个不同的进程可能返回相同的随机字节流。
从观察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
1个回答

8
实际上,该实现是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()时会被杀死。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接