aboutsummaryrefslogtreecommitdiff
path: root/cryptfs/nonce.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-10-04 21:36:16 +0200
committerJakob Unterwurzacher2015-10-04 21:36:16 +0200
commite6b7353f4e9516a712d7cd9dab7d73c6c79ae7d0 (patch)
tree96bc399eb220e00b585328a10333e0d9dd4bea37 /cryptfs/nonce.go
parentdf52aab0828f4cd67e003c66668ccfcba90ab798 (diff)
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.
Diffstat (limited to 'cryptfs/nonce.go')
-rw-r--r--cryptfs/nonce.go50
1 files 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
}