@@ -1772,11 +1772,53 @@ else
1772
1772
}
1773
1773
}
1774
1774
1775
+ version (linux )
1776
+ {
1777
+ // `getrandom()` was introduced in Linux 3.17.
1778
+
1779
+ // Shim for missing bindings in druntime
1780
+ version (none )
1781
+ import core.sys.linux.sys.random : getrandom;
1782
+ else
1783
+ {
1784
+ import core.sys.posix.sys.types : ssize_t ;
1785
+ extern extern (C) ssize_t getrandom(
1786
+ void * buf,
1787
+ size_t buflen,
1788
+ uint flags,
1789
+ ) @system nothrow @nogc ;
1790
+ }
1791
+ }
1792
+
1775
1793
/**
1776
1794
A "good" seed for initializing random number engines. Initializing
1777
1795
with $(D_PARAM unpredictableSeed) makes engines generate different
1778
1796
random number sequences every run.
1779
1797
1798
+ This function utilizes the system $(I cryptographically-secure pseudo-random
1799
+ number generator (CSPRNG)) or $(I pseudo-random number generator (PRNG))
1800
+ where available and implemented (currently `arc4random` on applicable BSD
1801
+ systems or `getrandom` on Linux) to generate “high quality” pseudo-random
1802
+ numbers – if possible.
1803
+ As a consequence, calling it may block under certain circumstances (typically
1804
+ during early boot when the system's entropy pool has not yet been
1805
+ initialized).
1806
+
1807
+ On x86 CPU models which support the `RDRAND` instruction, that will be used
1808
+ when no more specialized randomness source is implemented.
1809
+
1810
+ In the future, further platform-specific PRNGs may be incorporated.
1811
+
1812
+ Warning:
1813
+ $(B This function must not be used for cryptographic purposes.)
1814
+ Despite being implemented for certain targets, there are no guarantees
1815
+ that it sources its randomness from a CSPRNG.
1816
+ The implementation also includes a fallback option that provides very little
1817
+ randomness and is used when no better source of randomness is available or
1818
+ integrated on the target system.
1819
+ As written earlier, this function only aims to provide randomness for seeding
1820
+ ordinary (non-cryptographic) PRNG engines.
1821
+
1780
1822
Returns:
1781
1823
A single unsigned integer seed value, different on each successive call
1782
1824
Note:
@@ -1788,7 +1830,25 @@ how excellent the source of entropy is.
1788
1830
*/
1789
1831
@property uint unpredictableSeed() @trusted nothrow @nogc
1790
1832
{
1791
- version (AnyARC4Random)
1833
+ version (linux )
1834
+ {
1835
+ uint buffer;
1836
+
1837
+ /*
1838
+ getrandom(2):
1839
+ If the _urandom_ source has been initialized, reads of up to
1840
+ 256 bytes will always return as many bytes as requested and
1841
+ will not be interrupted by signals. No such guarantees apply
1842
+ for larger buffer sizes.
1843
+ */
1844
+ static assert (buffer.sizeof <= 256 );
1845
+
1846
+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1847
+ assert (status == buffer.sizeof);
1848
+
1849
+ return buffer;
1850
+ }
1851
+ else version (AnyARC4Random)
1792
1852
{
1793
1853
return arc4random ();
1794
1854
}
@@ -1837,7 +1897,25 @@ if (isUnsigned!UIntType)
1837
1897
// / ditto
1838
1898
@property UIntType unpredictableSeed() @nogc nothrow @trusted
1839
1899
{
1840
- version (AnyARC4Random)
1900
+ version (linux )
1901
+ {
1902
+ UIntType buffer;
1903
+
1904
+ /*
1905
+ getrandom(2):
1906
+ If the _urandom_ source has been initialized, reads of up to
1907
+ 256 bytes will always return as many bytes as requested and
1908
+ will not be interrupted by signals. No such guarantees apply
1909
+ for larger buffer sizes.
1910
+ */
1911
+ static assert (buffer.sizeof <= 256 );
1912
+
1913
+ const status = (() @trusted => getrandom(&buffer, buffer.sizeof, 0 ))();
1914
+ assert (status == buffer.sizeof);
1915
+
1916
+ return buffer;
1917
+ }
1918
+ else version (AnyARC4Random)
1841
1919
{
1842
1920
static if (UIntType.sizeof <= uint .sizeof)
1843
1921
{
0 commit comments