size_t RNG_SystemRNG(void *dest, size_t maxLen) { HMODULE hModule; RtlGenRandomFn pRtlGenRandom; CryptAcquireContextAFn pCryptAcquireContextA; CryptReleaseContextFn pCryptReleaseContext; CryptGenRandomFn pCryptGenRandom; HCRYPTPROV hCryptProv; size_t bytes = 0; usedWindowsPRNG = PR_FALSE; hModule = LoadLibrary("advapi32.dll"); if (hModule == NULL) { return rng_systemFromNoise(dest,maxLen); } pRtlGenRandom = (RtlGenRandomFn) GetProcAddress(hModule, "SystemFunction036"); if (pRtlGenRandom) { if (pRtlGenRandom(dest, maxLen)) { bytes = maxLen; usedWindowsPRNG = PR_TRUE; } else { bytes = rng_systemFromNoise(dest,maxLen); } goto done; } pCryptAcquireContextA = (CryptAcquireContextAFn) GetProcAddress(hModule, "CryptAcquireContextA"); pCryptReleaseContext = (CryptReleaseContextFn) GetProcAddress(hModule, "CryptReleaseContext"); pCryptGenRandom = (CryptGenRandomFn) GetProcAddress(hModule, "CryptGenRandom"); if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) { bytes = rng_systemFromNoise(dest,maxLen); goto done; } if (pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (pCryptGenRandom(hCryptProv, maxLen, dest)) { bytes = maxLen; usedWindowsPRNG = PR_TRUE; } pCryptReleaseContext(hCryptProv, 0); } if (bytes == 0) { bytes = rng_systemFromNoise(dest,maxLen); } done: FreeLibrary(hModule); return bytes; }
size_t RNG_SystemRNG(void *dest, size_t maxLen) { FILE *file; size_t bytes; size_t fileBytes = 0; unsigned char *buffer = dest; file = fopen("/dev/urandom", "r"); if (file == NULL) { return rng_systemFromNoise(dest, maxLen); } /* Set buffering mode to unbuffered I/O to avoid reading more bytes * than we need from /dev/urandom. */ setvbuf(file, NULL, _IONBF, 0); while (maxLen > fileBytes) { bytes = maxLen - fileBytes; bytes = fread(buffer, 1, bytes, file); if (bytes == 0) break; fileBytes += bytes; buffer += bytes; } fclose(file); if (fileBytes != maxLen) { PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ fileBytes = 0; } return fileBytes; }
size_t RNG_SystemRNG(void *dest, size_t maxLen) { FILE *file; size_t bytes; size_t fileBytes = 0; unsigned char *buffer = dest; file = fopen("/dev/urandom", "r"); if (file == NULL) { return rng_systemFromNoise(dest, maxLen); } while (maxLen > fileBytes) { bytes = maxLen - fileBytes; bytes = fread(buffer, 1, bytes, file); if (bytes == 0) break; fileBytes += bytes; buffer += bytes; } fclose(file); if (fileBytes != maxLen) { PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ fileBytes = 0; } return fileBytes; }
size_t RNG_SystemRNG(void *dest, size_t maxLen) { FILE *file; int fd; int bytes; size_t fileBytes = 0; unsigned char *buffer = dest; file = fopen("/dev/urandom", "r"); if (file == NULL) { return rng_systemFromNoise(dest, maxLen); } /* Read from the underlying file descriptor directly to bypass stdio * buffering and avoid reading more bytes than we need from /dev/urandom. * NOTE: we can't use fread with unbuffered I/O because fread may return * EOF in unbuffered I/O mode on Android. */ fd = fileno(file); while (maxLen > fileBytes) { bytes = maxLen - fileBytes; bytes = read(fd, buffer, bytes); if (bytes <= 0) break; fileBytes += bytes; buffer += bytes; } fclose(file); if (fileBytes != maxLen) { PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ fileBytes = 0; } return fileBytes; }
/* * The Windows CE and Windows Mobile FIPS Security Policy, page 13, * (http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp825.pdf) * says CeGenRandom is the right function to call for creating a seed * for a random number generator. */ size_t RNG_SystemRNG(void *dest, size_t maxLen) { size_t bytes = 0; usedWindowsPRNG = PR_FALSE; if (CeGenRandom(maxLen, dest)) { bytes = maxLen; usedWindowsPRNG = PR_TRUE; } if (bytes == 0) { bytes = rng_systemFromNoise(dest,maxLen); } return bytes; }
size_t RNG_SystemRNG(void *dest, size_t maxLen) { return rng_systemFromNoise(dest,maxLen); }