package node import ( "crypto/aes" "crypto/cipher" "crypto/rand" ) // TODO: Use [32]byte for simplicity everywhere. type dataCipher struct { key [32]byte aead cipher.AEAD } func newDataCipher() *dataCipher { key := [32]byte{} if _, err := rand.Read(key[:]); err != nil { panic(err) } return newDataCipherFromKey(key) } // key must be 32 bytes. func newDataCipherFromKey(key [32]byte) *dataCipher { block, err := aes.NewCipher(key[:]) if err != nil { panic(err) } aead, err := cipher.NewGCM(block) if err != nil { panic(err) } return &dataCipher{key: key, aead: aead} } func (sc *dataCipher) Key() [32]byte { return sc.key } func (sc *dataCipher) Encrypt(h xHeader, data, out []byte) []byte { const s = dataHeaderSize out = out[:s+dataCipherOverhead+len(data)] h.Marshal(out[:s]) sc.aead.Seal(out[s:s], out[:s], data, nil) return out } func (sc *dataCipher) Decrypt(encrypted, out []byte) (data []byte, ok bool) { const s = dataHeaderSize if len(encrypted) < s+dataCipherOverhead { ok = false return } var err error data, err = sc.aead.Open(out[:0], encrypted[:s], encrypted[s:], nil) ok = err == nil return }