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.
This commit is contained in:
Jakob Unterwurzacher 2015-10-04 21:36:16 +02:00
parent df52aab082
commit e6b7353f4e
1 changed files with 15 additions and 35 deletions

View File

@ -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()
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)
}
n.low64++
if n.low64 == 0 {
// Counter has wrapped
n.high32++
}
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
}