¿La horquilla SecRandomCopyBytes de OS X es segura?

Muchos CSPRNG de espacio de usuario tienen un problema en el que después de la fork(2) , es posible que los dos processs diferentes devuelvan la misma secuencia de bytes aleatorios.

Desde la dtruss de dtruss , está claro que SecRandomCopyBytes es, como mínimo, sembrando desde /dev/random , pero ¿lo está haciendo de manera segura después de fork() ?

Con el siguiente código fuente:

 #include <Security/Security.h> int main() { uint8_t data[8]; SecRandomCopyBytes(kSecRandomDefault, 8, data); SecRandomCopyBytes(kSecRandomDefault, 8, data); printf("%llu\n", *(uint64_t *)data); } 

Obtengo lo siguiente de dtruss (con cosas irrelevantes eliminadas):

 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 

La implementación es en realidad 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); } 

Entonces el código real está aquí:

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

Los comentarios en el include para CCRandomCopyBytes indican que es fork () seguro:

No es conveniente llamar a los generadores de numbers aleatorios del sistema directamente. En el caso simple de llamar / dev / aleatorio, la persona que llama debe abrir el dispositivo y cerrarlo, además de administrarlo mientras está abierto. Este module tiene como razón de ser inmediata el inconveniente de hacer esto. Gestiona un descriptor de file a / dev / random que incluye el procesamiento de exception de lo que sucede en un fork () y exec (). Llame a CCRandomCopyBytes () y se administran todos los bits fiddly para usted. Simplemente sigue adelante con lo que realmente estabas tratando de hacer. […]

En mi propia testing rápida, el niño muere cuando invoca SecRandomCopyBytes ()