make std/sysrand better (#17360)

This commit is contained in:
flywind
2021-03-15 21:07:27 +08:00
committed by GitHub
parent 283d9abc84
commit 51a04a3674

View File

@@ -258,26 +258,28 @@ else:
# see: https://www.2uo.de/myths-about-urandom/ which justifies using urandom instead of random
let fd = posix.open("/dev/urandom", O_RDONLY)
defer: discard posix.close(fd)
if fd > 0:
var stat: Stat
if fstat(fd, stat) != -1 and S_ISCHR(stat.st_mode):
let
chunks = (size - 1) div batchSize
left = size - chunks * batchSize
for i in 0 ..< chunks:
let readBytes = posix.read(fd, addr dest[result], batchSize)
if readBytes < 0:
return readBytes
inc(result, batchSize)
result = posix.read(fd, addr dest[result], left)
else:
result = -1
else:
if fd < 0:
result = -1
else:
try:
var stat: Stat
if fstat(fd, stat) != -1 and S_ISCHR(stat.st_mode):
let
chunks = (size - 1) div batchSize
left = size - chunks * batchSize
for i in 0 ..< chunks:
let readBytes = posix.read(fd, addr dest[result], batchSize)
if readBytes < 0:
return readBytes
inc(result, batchSize)
result = posix.read(fd, addr dest[result], left)
else:
result = -1
finally:
discard posix.close(fd)
proc urandomInternalImpl(dest: var openArray[byte]): int {.inline.} =
when batchImplOS:
@@ -291,6 +293,10 @@ proc urandom*(dest: var openArray[byte]): bool =
##
## If `dest` is empty, `urandom` immediately returns success,
## without calling underlying operating system api.
##
## .. warning:: The code hasn't been audited by cryptography experts and
## is provided as-is without guarantees. Use at your own risks. For production
## systems we advise you to request an external audit.
result = true
when defined(js): discard urandomInternalImpl(dest)
else:
@@ -304,6 +310,10 @@ proc urandom*(dest: var openArray[byte]): bool =
proc urandom*(size: Natural): seq[byte] {.inline.} =
## Returns random bytes suitable for cryptographic use.
##
## .. warning:: The code hasn't been audited by cryptography experts and
## is provided as-is without guarantees. Use at your own risks. For production
## systems we advise you to request an external audit.
result = newSeq[byte](size)
when defined(js): discard urandomInternalImpl(result)
else: