// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #include "rust_globals.h" #include "rust_rng.h" #include "rust_util.h" #ifdef __WIN32__ void win32_require(LPCTSTR fn, BOOL ok) { if (!ok) { LPTSTR buf; DWORD err = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL ); fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf); LocalFree((HLOCAL)buf); abort(); } } #endif void rng_gen_seed(uint8_t* dest, size_t size) { #ifdef __WIN32__ HCRYPTPROV hProv; win32_require (_T("CryptAcquireContext"), CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); win32_require (_T("CryptGenRandom"), CryptGenRandom(hProv, size, (BYTE*) dest)); win32_require (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); #else int fd = open("/dev/urandom", O_RDONLY); if (fd == -1) { fprintf(stderr, "error opening /dev/urandom: %s", strerror(errno)); abort(); } size_t amount = 0; do { ssize_t ret = read(fd, dest+amount, size-amount); if (ret < 0) { fprintf(stderr, "error reading /dev/urandom: %s", strerror(errno)); abort(); } else if (ret == 0) { fprintf(stderr, "somehow hit eof reading from /dev/urandom"); abort(); } amount += (size_t)ret; } while (amount < size); int ret = close(fd); if (ret != 0) { fprintf(stderr, "error closing /dev/urandom: %s", strerror(errno)); // FIXME #3697: Why does this fail sometimes? // abort(); } #endif } // // Local Variables: // mode: C++ // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4 // buffer-file-coding-system: utf-8-unix // End: //