Seed math/rand with crypto/rand (#359)

* Use crypto/rand to seed math/rand instead of using the default seed

* Better seeding+generation and fallback on crypto/rand.Read failure

* Remove user warning
This commit is contained in:
Roland Bracewell Shoemaker 2016-06-04 23:51:30 -07:00 committed by Miek Gieben
parent bd738b30b1
commit 3f53d75269
2 changed files with 24 additions and 2 deletions

View File

@ -203,3 +203,9 @@ func BenchmarkUnpackMsg(b *testing.B) {
_ = msg.Unpack(msgBuf)
}
}
func BenchmarkIdGeneration(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = id()
}
}

20
msg.go
View File

@ -11,15 +11,30 @@ package dns
//go:generate go run msg_generate.go
import (
crand "crypto/rand"
"encoding/binary"
"encoding/hex"
"math/big"
"math/rand"
"net"
"reflect"
"strconv"
"time"
)
func init() {
// Initialize default math/rand source using crypto/rand to provide better
// security without the performance trade-off.
buf := make([]byte, 8)
_, err := crand.Read(buf)
if err != nil {
// Failed to read from cryptographic source, fallback to default initial
// seed (1) by returning early
return
}
seed := binary.BigEndian.Uint64(buf)
rand.Seed(int64(seed))
}
const maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
var (
@ -1911,7 +1926,8 @@ func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
// id returns a 16 bits random number to be used as a
// message id. The random provided should be good enough.
func id() uint16 {
return uint16(rand.Int()) ^ uint16(time.Now().Nanosecond())
id32 := rand.Uint32()
return uint16(id32)
}
// Copy returns a new RR which is a deep-copy of r.