aboutsummaryrefslogtreecommitdiff
path: root/cryptfs/nonce.go
diff options
context:
space:
mode:
Diffstat (limited to 'cryptfs/nonce.go')
-rw-r--r--cryptfs/nonce.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/cryptfs/nonce.go b/cryptfs/nonce.go
new file mode 100644
index 0000000..3803b8c
--- /dev/null
+++ b/cryptfs/nonce.go
@@ -0,0 +1,55 @@
+package cryptfs
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "sync"
+ "crypto/rand"
+)
+
+type nonce96 struct {
+ lock sync.Mutex
+ high32 uint32
+ low64 uint64
+ ready int
+}
+
+var gcmNonce nonce96
+
+func (n *nonce96) randBytes(len int) []byte {
+ b := make([]byte, len)
+ _, err := rand.Read(b)
+ if err != nil {
+ panic("Could not get random bytes for nonce")
+ }
+ return b
+}
+
+func (n *nonce96) init() {
+ b := n.randBytes(8)
+ n.low64 = binary.BigEndian.Uint64(b)
+ b = n.randBytes(4)
+ n.high32 = binary.BigEndian.Uint32(b)
+ n.ready = 1
+ return
+}
+
+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++
+ }
+ 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
+}