github.com/slackhq/nebula@v1.9.0/noise.go (about) 1 package nebula 2 3 import ( 4 "crypto/cipher" 5 "encoding/binary" 6 "errors" 7 8 "github.com/flynn/noise" 9 ) 10 11 type endianness interface { 12 PutUint64(b []byte, v uint64) 13 } 14 15 var noiseEndianness endianness = binary.BigEndian 16 17 type NebulaCipherState struct { 18 c noise.Cipher 19 //k [32]byte 20 //n uint64 21 } 22 23 func NewNebulaCipherState(s *noise.CipherState) *NebulaCipherState { 24 return &NebulaCipherState{c: s.Cipher()} 25 26 } 27 28 // EncryptDanger encrypts and authenticates a given payload. 29 // 30 // out is a destination slice to hold the output of the EncryptDanger operation. 31 // - ad is additional data, which will be authenticated and appended to out, but not encrypted. 32 // - plaintext is encrypted, authenticated and appended to out. 33 // - n is a nonce value which must never be re-used with this key. 34 // - nb is a buffer used for temporary storage in the implementation of this call, which should 35 // be re-used by callers to minimize garbage collection. 36 func (s *NebulaCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) { 37 if s != nil { 38 // TODO: Is this okay now that we have made messageCounter atomic? 39 // Alternative may be to split the counter space into ranges 40 //if n <= s.n { 41 // return nil, errors.New("CRITICAL: a duplicate counter value was used") 42 //} 43 //s.n = n 44 nb[0] = 0 45 nb[1] = 0 46 nb[2] = 0 47 nb[3] = 0 48 noiseEndianness.PutUint64(nb[4:], n) 49 out = s.c.(cipher.AEAD).Seal(out, nb, plaintext, ad) 50 //l.Debugf("Encryption: outlen: %d, nonce: %d, ad: %s, plainlen %d", len(out), n, ad, len(plaintext)) 51 return out, nil 52 } else { 53 return nil, errors.New("no cipher state available to encrypt") 54 } 55 } 56 57 func (s *NebulaCipherState) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) { 58 if s != nil { 59 nb[0] = 0 60 nb[1] = 0 61 nb[2] = 0 62 nb[3] = 0 63 noiseEndianness.PutUint64(nb[4:], n) 64 return s.c.(cipher.AEAD).Open(out, nb, ciphertext, ad) 65 } else { 66 return []byte{}, nil 67 } 68 } 69 70 func (s *NebulaCipherState) Overhead() int { 71 if s != nil { 72 return s.c.(cipher.AEAD).Overhead() 73 } 74 return 0 75 }