diff options
author | flywind <xzsflywind@gmail.com> | 2021-03-15 21:07:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-15 14:07:27 +0100 |
commit | 51a04a3674d62707506774b11a4376a914735aeb (patch) | |
tree | 48462cc77fb79d8e87eb0fa03c76d59f0f279007 /lib/std | |
parent | 283d9abc84a9a71b88bb34b66f15157b1307e11c (diff) | |
download | Nim-51a04a3674d62707506774b11a4376a914735aeb.tar.gz |
make std/sysrand better (#17360)
Diffstat (limited to 'lib/std')
-rw-r--r-- | lib/std/sysrand.nim | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/std/sysrand.nim b/lib/std/sysrand.nim index 603c132e8..c9908143c 100644 --- a/lib/std/sysrand.nim +++ b/lib/std/sysrand.nim @@ -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: |