1 /* 2 * Hunt - A high-level D Programming Language Web framework that encourages rapid development and clean, pragmatic design. 3 * 4 * Copyright (C) 2015-2019, HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.framework.util.Random; 13 14 import std.stdio; 15 import std.exception; 16 17 version (CRuntime_Bionic) 18 version = SecureARC4Random; // ChaCha20 19 version (OSX) 20 version = SecureARC4Random; // AES 21 version (OpenBSD) 22 version = SecureARC4Random; // ChaCha20 23 version (NetBSD) 24 version = SecureARC4Random; // ChaCha20 25 26 // Insecure arc4random implementations are deliberately not enabled. 27 // If a cryptographically secure PRNG is not required, they can be used. 28 //version (CRuntime_UClibc) 29 // version = LegacyARC4Random; // ARC4 30 //version (FreeBSD) 31 // version = LegacyARC4Random; // ARC4 32 //version (DragonFlyBSD) 33 // version = LegacyARC4Random; // ARC4 34 //version (BSD) 35 // version = LegacyARC4Random; // Unknown implementation 36 37 // ubyte[] getRandom(ushort len = 64) 38 // { 39 // assert(len); 40 // ubyte[] buffer; 41 // buffer.length = len; 42 // version(Windows){ 43 // HCRYPTPROV hCryptProv; 44 // assert(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) != 0); 45 // CryptGenRandom(hCryptProv, cast(DWORD)buffer.length, buffer.ptr); 46 // scope(exit)CryptReleaseContext(hCryptProv, 0); 47 // }else version(SecureARC4Random){ 48 // arc4random_buf(buffer.ptr, len); 49 // }else{ 50 // import core.stdc.stdio : FILE, _IONBF, fopen, fclose, fread, setvbuf; 51 // auto file = fopen("/dev/urandom","rb"); 52 // scope(exit)fclose(file); 53 // if(file is null)throw new Exception("Failed to open /dev/urandom"); 54 // if(setvbuf(file, null, 0, _IONBF) != 0)throw new 55 // Exception("Failed to disable buffering for random number file handle"); 56 // if(fread(buffer.ptr, buffer.length, 1, file) != 1)throw new 57 // Exception("Failed to read next random number"); 58 // } 59 // return buffer; 60 // } 61 62 63 64 version(Windows){ 65 static if (__VERSION__ >= 2070) 66 { 67 import core.sys.windows.windows; 68 } 69 else 70 { 71 import std.c.windows.windows; 72 import std.conv; 73 74 } 75 76 pragma(lib, "advapi32.lib"); 77 78 private extern (Windows) nothrow 79 { 80 alias HCRYPTPROV = size_t; 81 82 enum LPCTSTR NULL = cast(LPCTSTR) 0; 83 enum DWORD PROV_RSA_FULL = 1; 84 enum DWORD CRYPT_VERIFYCONTEXT = 0xF0000000; 85 86 BOOL CryptAcquireContextA(HCRYPTPROV* phProv, LPCTSTR pszContainer, 87 LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags); 88 alias CryptAcquireContext = CryptAcquireContextA; 89 90 BOOL CryptReleaseContext(HCRYPTPROV hProv, DWORD dwFlags); 91 92 BOOL CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer); 93 } 94 }else version(SecureARC4Random){ 95 extern(C) @nogc nothrow private @system 96 { 97 void arc4random_buf(scope void* buf, size_t nbytes); 98 } 99 }