Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add system random to stdlib: std/sysrand #16459

Merged
merged 69 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
ca1887a
close #10307(add testcase for #10307)
ringabout Nov 4, 2020
f1d6740
Merge
ringabout Dec 24, 2020
469d159
add secrets to stdlib
ringabout Dec 24, 2020
5856729
rename
ringabout Dec 24, 2020
335427b
fix
ringabout Dec 24, 2020
ff1153d
fix
ringabout Dec 24, 2020
cfa81bf
Update tests/magics/t10307.nim
ringabout Dec 24, 2020
39b6aab
update secrets
ringabout Jan 23, 2021
6cfe937
fix
ringabout Jan 24, 2021
0f9fdc6
fix
ringabout Jan 24, 2021
170c61d
add openbsd
ringabout Jan 24, 2021
e60ac45
openbsd
ringabout Jan 24, 2021
2766827
add macosx
ringabout Jan 24, 2021
d52702c
better
ringabout Jan 24, 2021
faa30cb
Merge remote-tracking branch 'upstream/devel' into didodido
ringabout Jan 24, 2021
66758ca
fix
ringabout Jan 24, 2021
410dfc8
fix
ringabout Jan 24, 2021
cf0eea5
better interface
ringabout Jan 24, 2021
430a9cf
fix
ringabout Jan 24, 2021
94d90e8
add js support
ringabout Jan 24, 2021
a93d360
add notes
ringabout Jan 24, 2021
153c442
add freebsd
ringabout Jan 24, 2021
88e86f0
better
ringabout Jan 24, 2021
a67e2a8
better
ringabout Jan 24, 2021
1e1d01c
fix
ringabout Jan 24, 2021
af90ab7
add tests
ringabout Jan 25, 2021
918ddb1
minor clean
ringabout Jan 25, 2021
4ee409b
slight better
ringabout Jan 25, 2021
a856a33
better
ringabout Jan 25, 2021
9da336b
fix
ringabout Jan 25, 2021
67600a1
better
ringabout Jan 25, 2021
66560b0
rename
ringabout Jan 25, 2021
3a9affe
better type
ringabout Jan 25, 2021
4c638a2
add comments
ringabout Jan 25, 2021
b351779
fix header
ringabout Jan 25, 2021
08971f8
fix
ringabout Jan 25, 2021
05c5d16
fix name
ringabout Jan 25, 2021
53a9aca
fix header
ringabout Jan 25, 2021
2dd08fd
a bit better
ringabout Jan 26, 2021
84889b9
fix
ringabout Jan 26, 2021
f2b02db
freebsd fallback to dev/urandom
ringabout Jan 26, 2021
9972b31
restore
ringabout Jan 26, 2021
5f1aa74
better
ringabout Jan 26, 2021
5e258e7
better
ringabout Jan 26, 2021
6a34803
better
ringabout Jan 26, 2021
f0b5fda
add nodejs support
ringabout Jan 26, 2021
90ed94f
done
ringabout Jan 26, 2021
edf1293
better style
ringabout Jan 26, 2021
e376ea4
fix
ringabout Jan 26, 2021
4c86fa5
better
ringabout Jan 26, 2021
7bffe1e
fix
ringabout Jan 26, 2021
dd61e99
typo
ringabout Jan 26, 2021
1fc359a
resolve comments
ringabout Jan 27, 2021
bf592f6
better
ringabout Jan 27, 2021
2445403
better comments
ringabout Jan 27, 2021
8fffc5d
fix errors
ringabout Jan 27, 2021
99f6a1a
fix
ringabout Jan 27, 2021
1b88b84
better js
ringabout Jan 27, 2021
ec67a1a
reduce size
ringabout Jan 27, 2021
9836c5b
better
ringabout Jan 27, 2021
8ee923e
better impl
ringabout Jan 27, 2021
c1cec17
small
ringabout Jan 27, 2021
2f716fc
better
ringabout Jan 27, 2021
cb383a7
Merge remote-tracking branch 'upstream/devel' into didodido
ringabout Jan 27, 2021
4693e8f
finish
ringabout Jan 28, 2021
dbda6d3
Merge branch 'devel' into didodido
ringabout Feb 1, 2021
4cc557d
Merge remote-tracking branch 'upstream/devel' into didodido
ringabout Feb 5, 2021
12edec2
fix
ringabout Feb 5, 2021
8d2e7e2
fix comments
ringabout Feb 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions lib/std/secrets.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import os
ringabout marked this conversation as resolved.
Show resolved Hide resolved

runnableExamples:
doAssert urandom(0).len == 0
doAssert urandom(10).len == 10
doAssert urandom(20).len == 20
doAssert urandom(120).len == 120
ringabout marked this conversation as resolved.
Show resolved Hide resolved


when defined(posix):
import posix

template processReadBytes(readBytes: int, p: pointer) =
ringabout marked this conversation as resolved.
Show resolved Hide resolved
if readBytes == 0:
break
elif readBytes > 0:
inc(result, readBytes)
cast[ptr pointer](p)[] = cast[pointer](cast[ByteAddress](p) + readBytes)
else:
ringabout marked this conversation as resolved.
Show resolved Hide resolved
if osLastError().int in {EINTR, EAGAIN}:
discard
else:
result = -1
break

proc getDevUrandom(p: pointer, size: int): int =
let fd = posix.open("/dev/urandom", O_RDONLY)
ringabout marked this conversation as resolved.
Show resolved Hide resolved

if fd > 0:
var stat: Stat
if fstat(fd, stat) != -1 and S_ISCHR(stat.st_mode):
while result < size:
let readBytes = posix.read(fd, p, size - result)
processReadBytes(readBytes, p)

discard posix.close(fd)

when defined(windows):
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
import winlean

type
ringabout marked this conversation as resolved.
Show resolved Hide resolved
PVOID = pointer
BCRYPT_ALG_HANDLE = PVOID
PUCHAR = ptr cuchar
NTSTATUS = clong

const
STATUS_SUCCESS = 0x00000000
BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002

proc bCryptGenRandom(
hAlgorithm: BCRYPT_ALG_HANDLE,
pbBuffer: PUCHAR,
cbBuffer: ULONG,
dwFlags: ULONG
): NTSTATUS {.stdcall, importc: "BCryptGenRandom", dynlib: "Bcrypt.dll".}


proc randomBytes(pbBuffer: pointer, cbBuffer: ULONG): int =
bCryptGenRandom(nil, cast[PUCHAR](pbBuffer), cbBuffer,
BCRYPT_USE_SYSTEM_PREFERRED_RNG)

proc urandom*(p: pointer, size: int): int =
result = randomBytes(p, ULONG(size))

proc urandom*(size: int): string =
result = newString(size)
if urandom(result.cstring, ULONG(size)) != STATUS_SUCCESS:
raiseOsError(osLastError())

elif defined(linux):
let SYS_getrandom {.importc: "SYS_getrandom", header: "<syscall.h>".}: clong
ringabout marked this conversation as resolved.
Show resolved Hide resolved

proc syscall(n: clong, buf: pointer, bufLen: cint, flags: cuint): int {.importc: "syscall", header: "syscall.h".}
ringabout marked this conversation as resolved.
Show resolved Hide resolved

ringabout marked this conversation as resolved.
Show resolved Hide resolved
proc randomBytes(p: pointer, size: int): int =
while result < size:
let readBytes = syscall(SYS_getrandom, p, cint(size - result), 0)
processReadBytes(readBytes, p)

proc urandom*(p: pointer, size: int): int =
result = randomBytes(p, size)
if result < 0:
result = getDevUrandom(p, size)

proc urandom*(size: int): string =
result = newString(size)
if urandom(result.cstring, size) < 0:
raiseOsError(osLastError())

else:
proc urandom*(p: pointer, size: int): int =
result = getDevUrandom(p, size)

ringabout marked this conversation as resolved.
Show resolved Hide resolved
proc urandom*(size: int): string =
ringabout marked this conversation as resolved.
Show resolved Hide resolved
result = newString(size)
if urandom(result.cstring, size) < 0:
raiseOsError(osLastError())
11 changes: 11 additions & 0 deletions tests/stdlib/tsecrets.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
discard """
targets: "c cpp"
"""

import std/secrets


doAssert urandom(0).len == 0
doAssert urandom(10).len == 10
doAssert urandom(20).len == 20
doAssert urandom(120).len == 120