From e6b7353f4e9516a712d7cd9dab7d73c6c79ae7d0 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 4 Oct 2015 21:36:16 +0200 Subject: Switch nonce generation to purely random The old implementation of counting up from a random starting point had the problem that is allowed an attacker to find out the write order of the blocks. --- cryptfs/nonce.go | 50 +++++++++++++++----------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/cryptfs/nonce.go b/cryptfs/nonce.go index 80134c3..0ba079b 100644 --- a/cryptfs/nonce.go +++ b/cryptfs/nonce.go @@ -1,56 +1,36 @@ package cryptfs import ( + "bytes" + "fmt" "crypto/rand" - "encoding/binary" "encoding/hex" - "sync" ) -type nonce96 struct { - lock sync.Mutex - high32 uint32 - low64 uint64 - ready int -} - -var gcmNonce nonce96 - // Get "n" random bytes from /dev/urandom or panic func RandBytes(n int) []byte { b := make([]byte, n) _, err := rand.Read(b) if err != nil { - panic("Could not get random bytes for nonce") + panic("Failed to read random bytes: " + err.Error()) } return b } -func (n *nonce96) init() { - b := RandBytes(8) - n.low64 = binary.BigEndian.Uint64(b) - b = RandBytes(4) - n.high32 = binary.BigEndian.Uint32(b) - n.ready = 1 - return +var gcmNonce nonce96 + +type nonce96 struct { + lastNonce []byte } +// Get a random 96 bit nonce func (n *nonce96) Get() []byte { - n.lock.Lock() - if n.ready == 0 { - n.init() - } - n.low64++ - if n.low64 == 0 { - // Counter has wrapped - n.high32++ + nonce := RandBytes(12) + Debug.Printf("nonce96.Get(): %s\n", hex.EncodeToString(nonce)) + if bytes.Equal(nonce, n.lastNonce) { + m := fmt.Sprintf("Got the same nonce twice: %s. This should never happen!", hex.EncodeToString(nonce)) + panic(m) } - r := make([]byte, 12) - binary.BigEndian.PutUint32(r[0:4], n.high32) - binary.BigEndian.PutUint64(r[4:12], n.low64) - n.lock.Unlock() - - Debug.Printf("nonce96.Get(): %s\n", hex.EncodeToString(r)) - - return r + n.lastNonce = nonce + return nonce } -- cgit v1.2.3