1 /** 2 * Interface to the OS CSPRNG. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <vladimir@thecybershadow.net> 12 */ 13 14 module ae.sys.osrng; 15 16 import std.conv : to; 17 18 version (CRuntime_Bionic) 19 version = SecureARC4Random; // ChaCha20 20 version (OSX) 21 version = SecureARC4Random; // AES 22 version (OpenBSD) 23 version = SecureARC4Random; // ChaCha20 24 version (NetBSD) 25 version = SecureARC4Random; // ChaCha20 26 27 // Not SecureARC4Random: 28 // CRuntime_UClibc (ARC4) 29 // FreeBSD (ARC4) 30 // DragonFlyBSD (ARC4) 31 32 version (Windows) 33 { 34 import ae.sys.windows; 35 36 import ae.sys.windows.imports; 37 mixin(importWin32!q{wincrypt}); 38 mixin(importWin32!q{windef}); 39 40 void genRandom(ubyte[] buf) 41 { 42 HCRYPTPROV hCryptProv; 43 wenforce(CryptAcquireContext(&hCryptProv, null, null, PROV_RSA_FULL, 0), "CryptAcquireContext"); 44 scope(exit) wenforce(CryptReleaseContext(hCryptProv, 0), "CryptReleaseContext"); 45 wenforce(CryptGenRandom(hCryptProv, buf.length.to!DWORD, buf.ptr), "CryptGenRandom"); 46 } 47 } 48 else 49 version (SecureARC4Random) 50 { 51 extern(C) private @nogc nothrow 52 { 53 void arc4random_buf(scope void* buf, size_t nbytes) @system; 54 } 55 56 void genRandom(ubyte[] buf) 57 { 58 arc4random_buf(buf.ptr, buf.length); 59 } 60 } 61 else 62 version (Posix) 63 { 64 import std.stdio; 65 import std.exception; 66 67 void genRandom(ubyte[] buf) 68 { 69 auto f = File("/dev/urandom"); 70 auto result = f.rawRead(buf); 71 enforce(result.length == buf.length, "Couldn't read enough random bytes"); 72 } 73 }