Commit 6820be25 authored by Keith Randall's avatar Keith Randall

runtime: clean up & go-ify the hash function seeder

Change-Id: I0e95f8a5962c547da20e19a356ae1cf8375c9107
Reviewed-on: https://go-review.googlesource.com/1270Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent b796cbc4
......@@ -332,18 +332,6 @@ func init() {
algarray[alg_MEM128].hash = aeshash
algarray[alg_STRING].hash = aeshashstr
// Initialize with random data so hash collisions will be hard to engineer.
var rnd unsafe.Pointer
var n int32
get_random_data(&rnd, &n)
if n > hashRandomBytes {
n = hashRandomBytes
}
memmove(unsafe.Pointer(&aeskeysched[0]), rnd, uintptr(n))
if n < hashRandomBytes {
// Not very random, but better than nothing.
for t := nanotime(); n < hashRandomBytes; n++ {
aeskeysched[n] = byte(t >> uint(8*(n%8)))
}
}
getRandomData(aeskeysched[:])
}
}
......@@ -45,20 +45,14 @@ func osinit() {
}
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/random\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -97,20 +97,14 @@ func osinit() {
ncpu = getncpu()
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/urandom\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -96,20 +96,14 @@ func osinit() {
ncpu = getncpu()
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/random\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -145,30 +145,18 @@ func osinit() {
ncpu = getproccount()
}
// Random bytes initialized at startup. These come
// from the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.c).
// byte* runtime·startup_random_data;
// uint32 runtime·startup_random_data_len;
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/random\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
if startup_random_data != nil {
*rnd = unsafe.Pointer(startup_random_data)
*rnd_len = int32(startup_random_data_len)
func getRandomData(r []byte) {
if startupRandomData != nil {
n := copy(r, startupRandomData)
extendRandom(r, n)
return
}
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -170,20 +170,14 @@ func osinit() {
ncpu = getncpu()
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/urandom\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -138,20 +138,14 @@ func osinit() {
ncpu = getncpu()
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/urandom\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -85,20 +85,14 @@ func crash() {
*(*int)(nil) = 0
}
var random_data [_HashRandomBytes]byte
var random_dev = []byte("/dev/random\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&random_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&random_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&random_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -148,24 +148,21 @@ func osinit() {
}
}
var random_data [_HashRandomBytes]byte
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
const (
prov_rsa_full = 1
crypt_verifycontext = 0xF0000000
)
var handle uintptr
*rnd = nil
*rnd_len = 0
n := 0
if stdcall5(_CryptAcquireContextW, uintptr(unsafe.Pointer(&handle)), 0, 0, prov_rsa_full, crypt_verifycontext) != 0 {
if stdcall3(_CryptGenRandom, handle, _HashRandomBytes, uintptr(unsafe.Pointer(&random_data[0]))) != 0 {
*rnd = unsafe.Pointer(&random_data[0])
*rnd_len = _HashRandomBytes
if stdcall3(_CryptGenRandom, handle, uintptr(len(r)), uintptr(unsafe.Pointer(&r[0]))) != 0 {
n = len(r)
}
stdcall2(_CryptReleaseContext, handle, 0)
}
extendRandom(r, n)
}
func goenvs() {
......
......@@ -165,20 +165,14 @@ func newosproc(mp *m, _ unsafe.Pointer) {
}
}
var urandom_data [_HashRandomBytes]byte
var urandom_dev = []byte("/dev/random\x00")
//go:nosplit
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
func getRandomData(r []byte) {
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
*rnd = unsafe.Pointer(&urandom_data[0])
*rnd_len = _HashRandomBytes
} else {
*rnd = nil
*rnd_len = 0
}
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
close(fd)
extendRandom(r, int(n))
}
func goenvs() {
......
......@@ -29,8 +29,7 @@ func sysargs(argc int32, argv **byte) {
_vdso = auxv[i+1]
case _AT_RANDOM:
startup_random_data = (*byte)(unsafe.Pointer(uintptr(auxv[i+1])))
startup_random_data_len = 16
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
}
}
}
......@@ -475,16 +475,33 @@ const (
_Structrnd = regSize
)
var startup_random_data *byte
var startup_random_data_len uint32
// startup_random_data holds random bytes initialized at startup. These come from
// the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.go or os_linux_386.go).
var startupRandomData []byte
// extendRandom extends the random numbers in r[:n] to the whole slice r.
// Treats n<0 as n==0.
func extendRandom(r []byte, n int) {
if n < 0 {
n = 0
}
for n < len(r) {
// Extend random bits using hash function & time seed
w := n
if w > 16 {
w = 16
}
h := memhash(unsafe.Pointer(&r[n-w]), uintptr(w), uintptr(nanotime()))
for i := 0; i < ptrSize && n < len(r); i++ {
r[n] = byte(h)
n++
h >>= 8
}
}
}
var invalidptr int32
const (
// hashinit wants this many random bytes
_HashRandomBytes = 32
)
/*
* deferred subroutine calls
*/
......
......@@ -321,8 +321,7 @@ func sysargs(argc int32, argv **byte) {
vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
case _AT_RANDOM:
startup_random_data = (*byte)(unsafe.Pointer(uintptr(av.a_val)))
startup_random_data_len = 16
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(av.a_val)))[:]
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment