56 lines
893 B
Go
56 lines
893 B
Go
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
|
|
}
|