Skip to content

Commit 6820be2

Browse files
committed
runtime: clean up & go-ify the hash function seeder
Change-Id: I0e95f8a5962c547da20e19a356ae1cf8375c9107 Reviewed-on: https://go-review.googlesource.com/1270 Reviewed-by: Russ Cox <[email protected]>
1 parent b796cbc commit 6820be2

13 files changed

+59
-113
lines changed

src/runtime/alg.go

+1-13
Original file line numberDiff line numberDiff line change
@@ -332,18 +332,6 @@ func init() {
332332
algarray[alg_MEM128].hash = aeshash
333333
algarray[alg_STRING].hash = aeshashstr
334334
// Initialize with random data so hash collisions will be hard to engineer.
335-
var rnd unsafe.Pointer
336-
var n int32
337-
get_random_data(&rnd, &n)
338-
if n > hashRandomBytes {
339-
n = hashRandomBytes
340-
}
341-
memmove(unsafe.Pointer(&aeskeysched[0]), rnd, uintptr(n))
342-
if n < hashRandomBytes {
343-
// Not very random, but better than nothing.
344-
for t := nanotime(); n < hashRandomBytes; n++ {
345-
aeskeysched[n] = byte(t >> uint(8*(n%8)))
346-
}
347-
}
335+
getRandomData(aeskeysched[:])
348336
}
349337
}

src/runtime/os1_darwin.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,14 @@ func osinit() {
4545
}
4646
}
4747

48-
var urandom_data [_HashRandomBytes]byte
4948
var urandom_dev = []byte("/dev/random\x00")
5049

5150
//go:nosplit
52-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
51+
func getRandomData(r []byte) {
5352
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
54-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
55-
*rnd = unsafe.Pointer(&urandom_data[0])
56-
*rnd_len = _HashRandomBytes
57-
} else {
58-
*rnd = nil
59-
*rnd_len = 0
60-
}
53+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
6154
close(fd)
55+
extendRandom(r, int(n))
6256
}
6357

6458
func goenvs() {

src/runtime/os1_dragonfly.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,14 @@ func osinit() {
9797
ncpu = getncpu()
9898
}
9999

100-
var urandom_data [_HashRandomBytes]byte
101100
var urandom_dev = []byte("/dev/urandom\x00")
102101

103102
//go:nosplit
104-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
103+
func getRandomData(r []byte) {
105104
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
106-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
107-
*rnd = unsafe.Pointer(&urandom_data[0])
108-
*rnd_len = _HashRandomBytes
109-
} else {
110-
*rnd = nil
111-
*rnd_len = 0
112-
}
105+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
113106
close(fd)
107+
extendRandom(r, int(n))
114108
}
115109

116110
func goenvs() {

src/runtime/os1_freebsd.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,14 @@ func osinit() {
9696
ncpu = getncpu()
9797
}
9898

99-
var urandom_data [_HashRandomBytes]byte
10099
var urandom_dev = []byte("/dev/random\x00")
101100

102101
//go:nosplit
103-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
102+
func getRandomData(r []byte) {
104103
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
105-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
106-
*rnd = unsafe.Pointer(&urandom_data[0])
107-
*rnd_len = _HashRandomBytes
108-
} else {
109-
*rnd = nil
110-
*rnd_len = 0
111-
}
104+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
112105
close(fd)
106+
extendRandom(r, int(n))
113107
}
114108

115109
func goenvs() {

src/runtime/os1_linux.go

+6-18
Original file line numberDiff line numberDiff line change
@@ -145,30 +145,18 @@ func osinit() {
145145
ncpu = getproccount()
146146
}
147147

148-
// Random bytes initialized at startup. These come
149-
// from the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.c).
150-
// byte* runtime·startup_random_data;
151-
// uint32 runtime·startup_random_data_len;
152-
153-
var urandom_data [_HashRandomBytes]byte
154148
var urandom_dev = []byte("/dev/random\x00")
155149

156-
//go:nosplit
157-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
158-
if startup_random_data != nil {
159-
*rnd = unsafe.Pointer(startup_random_data)
160-
*rnd_len = int32(startup_random_data_len)
150+
func getRandomData(r []byte) {
151+
if startupRandomData != nil {
152+
n := copy(r, startupRandomData)
153+
extendRandom(r, n)
161154
return
162155
}
163156
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
164-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
165-
*rnd = unsafe.Pointer(&urandom_data[0])
166-
*rnd_len = _HashRandomBytes
167-
} else {
168-
*rnd = nil
169-
*rnd_len = 0
170-
}
157+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
171158
close(fd)
159+
extendRandom(r, int(n))
172160
}
173161

174162
func goenvs() {

src/runtime/os1_netbsd.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,14 @@ func osinit() {
170170
ncpu = getncpu()
171171
}
172172

173-
var urandom_data [_HashRandomBytes]byte
174173
var urandom_dev = []byte("/dev/urandom\x00")
175174

176175
//go:nosplit
177-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
176+
func getRandomData(r []byte) {
178177
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
179-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
180-
*rnd = unsafe.Pointer(&urandom_data[0])
181-
*rnd_len = _HashRandomBytes
182-
} else {
183-
*rnd = nil
184-
*rnd_len = 0
185-
}
178+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
186179
close(fd)
180+
extendRandom(r, int(n))
187181
}
188182

189183
func goenvs() {

src/runtime/os1_openbsd.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -138,20 +138,14 @@ func osinit() {
138138
ncpu = getncpu()
139139
}
140140

141-
var urandom_data [_HashRandomBytes]byte
142141
var urandom_dev = []byte("/dev/urandom\x00")
143142

144143
//go:nosplit
145-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
144+
func getRandomData(r []byte) {
146145
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
147-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
148-
*rnd = unsafe.Pointer(&urandom_data[0])
149-
*rnd_len = _HashRandomBytes
150-
} else {
151-
*rnd = nil
152-
*rnd_len = 0
153-
}
146+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
154147
close(fd)
148+
extendRandom(r, int(n))
155149
}
156150

157151
func goenvs() {

src/runtime/os1_plan9.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,14 @@ func crash() {
8585
*(*int)(nil) = 0
8686
}
8787

88-
var random_data [_HashRandomBytes]byte
8988
var random_dev = []byte("/dev/random\x00")
9089

9190
//go:nosplit
92-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
91+
func getRandomData(r []byte) {
9392
fd := open(&random_dev[0], 0 /* O_RDONLY */, 0)
94-
if read(fd, unsafe.Pointer(&random_data), _HashRandomBytes) == _HashRandomBytes {
95-
*rnd = unsafe.Pointer(&random_data[0])
96-
*rnd_len = _HashRandomBytes
97-
} else {
98-
*rnd = nil
99-
*rnd_len = 0
100-
}
93+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
10194
close(fd)
95+
extendRandom(r, int(n))
10296
}
10397

10498
func goenvs() {

src/runtime/os1_windows.go

+5-8
Original file line numberDiff line numberDiff line change
@@ -148,24 +148,21 @@ func osinit() {
148148
}
149149
}
150150

151-
var random_data [_HashRandomBytes]byte
152-
153151
//go:nosplit
154-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
152+
func getRandomData(r []byte) {
155153
const (
156154
prov_rsa_full = 1
157155
crypt_verifycontext = 0xF0000000
158156
)
159157
var handle uintptr
160-
*rnd = nil
161-
*rnd_len = 0
158+
n := 0
162159
if stdcall5(_CryptAcquireContextW, uintptr(unsafe.Pointer(&handle)), 0, 0, prov_rsa_full, crypt_verifycontext) != 0 {
163-
if stdcall3(_CryptGenRandom, handle, _HashRandomBytes, uintptr(unsafe.Pointer(&random_data[0]))) != 0 {
164-
*rnd = unsafe.Pointer(&random_data[0])
165-
*rnd_len = _HashRandomBytes
160+
if stdcall3(_CryptGenRandom, handle, uintptr(len(r)), uintptr(unsafe.Pointer(&r[0]))) != 0 {
161+
n = len(r)
166162
}
167163
stdcall2(_CryptReleaseContext, handle, 0)
168164
}
165+
extendRandom(r, n)
169166
}
170167

171168
func goenvs() {

src/runtime/os3_solaris.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,14 @@ func newosproc(mp *m, _ unsafe.Pointer) {
165165
}
166166
}
167167

168-
var urandom_data [_HashRandomBytes]byte
169168
var urandom_dev = []byte("/dev/random\x00")
170169

171170
//go:nosplit
172-
func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
171+
func getRandomData(r []byte) {
173172
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
174-
if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
175-
*rnd = unsafe.Pointer(&urandom_data[0])
176-
*rnd_len = _HashRandomBytes
177-
} else {
178-
*rnd = nil
179-
*rnd_len = 0
180-
}
173+
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
181174
close(fd)
175+
extendRandom(r, int(n))
182176
}
183177

184178
func goenvs() {

src/runtime/os_linux_386.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ func sysargs(argc int32, argv **byte) {
2929
_vdso = auxv[i+1]
3030

3131
case _AT_RANDOM:
32-
startup_random_data = (*byte)(unsafe.Pointer(uintptr(auxv[i+1])))
33-
startup_random_data_len = 16
32+
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
3433
}
3534
}
3635
}

src/runtime/runtime2.go

+24-7
Original file line numberDiff line numberDiff line change
@@ -475,16 +475,33 @@ const (
475475
_Structrnd = regSize
476476
)
477477

478-
var startup_random_data *byte
479-
var startup_random_data_len uint32
478+
// startup_random_data holds random bytes initialized at startup. These come from
479+
// the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.go or os_linux_386.go).
480+
var startupRandomData []byte
481+
482+
// extendRandom extends the random numbers in r[:n] to the whole slice r.
483+
// Treats n<0 as n==0.
484+
func extendRandom(r []byte, n int) {
485+
if n < 0 {
486+
n = 0
487+
}
488+
for n < len(r) {
489+
// Extend random bits using hash function & time seed
490+
w := n
491+
if w > 16 {
492+
w = 16
493+
}
494+
h := memhash(unsafe.Pointer(&r[n-w]), uintptr(w), uintptr(nanotime()))
495+
for i := 0; i < ptrSize && n < len(r); i++ {
496+
r[n] = byte(h)
497+
n++
498+
h >>= 8
499+
}
500+
}
501+
}
480502

481503
var invalidptr int32
482504

483-
const (
484-
// hashinit wants this many random bytes
485-
_HashRandomBytes = 32
486-
)
487-
488505
/*
489506
* deferred subroutine calls
490507
*/

src/runtime/vdso_linux_amd64.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,7 @@ func sysargs(argc int32, argv **byte) {
321321
vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
322322

323323
case _AT_RANDOM:
324-
startup_random_data = (*byte)(unsafe.Pointer(uintptr(av.a_val)))
325-
startup_random_data_len = 16
324+
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(av.a_val)))[:]
326325
}
327326
}
328327
}

0 commit comments

Comments
 (0)