make std/sysrand better (#17360)
This commit is contained in:
parent
283d9abc84
commit
51a04a3674
1 changed files with 28 additions and 18 deletions
|
|
@ -258,26 +258,28 @@ else:
|
||||||
|
|
||||||
# see: https://www.2uo.de/myths-about-urandom/ which justifies using urandom instead of random
|
# see: https://www.2uo.de/myths-about-urandom/ which justifies using urandom instead of random
|
||||||
let fd = posix.open("/dev/urandom", O_RDONLY)
|
let fd = posix.open("/dev/urandom", O_RDONLY)
|
||||||
defer: discard posix.close(fd)
|
|
||||||
|
|
||||||
if fd > 0:
|
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:
|
|
||||||
result = -1
|
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.} =
|
proc urandomInternalImpl(dest: var openArray[byte]): int {.inline.} =
|
||||||
when batchImplOS:
|
when batchImplOS:
|
||||||
|
|
@ -291,6 +293,10 @@ proc urandom*(dest: var openArray[byte]): bool =
|
||||||
##
|
##
|
||||||
## If `dest` is empty, `urandom` immediately returns success,
|
## If `dest` is empty, `urandom` immediately returns success,
|
||||||
## without calling underlying operating system api.
|
## 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
|
result = true
|
||||||
when defined(js): discard urandomInternalImpl(dest)
|
when defined(js): discard urandomInternalImpl(dest)
|
||||||
else:
|
else:
|
||||||
|
|
@ -304,6 +310,10 @@ proc urandom*(dest: var openArray[byte]): bool =
|
||||||
|
|
||||||
proc urandom*(size: Natural): seq[byte] {.inline.} =
|
proc urandom*(size: Natural): seq[byte] {.inline.} =
|
||||||
## Returns random bytes suitable for cryptographic use.
|
## 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)
|
result = newSeq[byte](size)
|
||||||
when defined(js): discard urandomInternalImpl(result)
|
when defined(js): discard urandomInternalImpl(result)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue