3
0

noise.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package nebula
  2. import (
  3. "crypto/cipher"
  4. "encoding/binary"
  5. "errors"
  6. "github.com/flynn/noise"
  7. )
  8. type endianness interface {
  9. PutUint64(b []byte, v uint64)
  10. }
  11. var noiseEndianness endianness = binary.BigEndian
  12. type NebulaCipherState struct {
  13. c noise.Cipher
  14. //k [32]byte
  15. //n uint64
  16. }
  17. func NewNebulaCipherState(s *noise.CipherState) *NebulaCipherState {
  18. return &NebulaCipherState{c: s.Cipher()}
  19. }
  20. func (s *NebulaCipherState) EncryptDanger(out, ad, plaintext []byte, n uint64, nb []byte) ([]byte, error) {
  21. if s != nil {
  22. // TODO: Is this okay now that we have made messageCounter atomic?
  23. // Alternative may be to split the counter space into ranges
  24. //if n <= s.n {
  25. // return nil, errors.New("CRITICAL: a duplicate counter value was used")
  26. //}
  27. //s.n = n
  28. nb[0] = 0
  29. nb[1] = 0
  30. nb[2] = 0
  31. nb[3] = 0
  32. noiseEndianness.PutUint64(nb[4:], n)
  33. out = s.c.(cipher.AEAD).Seal(out, nb, plaintext, ad)
  34. //l.Debugf("Encryption: outlen: %d, nonce: %d, ad: %s, plainlen %d", len(out), n, ad, len(plaintext))
  35. return out, nil
  36. } else {
  37. return nil, errors.New("no cipher state available to encrypt")
  38. }
  39. }
  40. func (s *NebulaCipherState) DecryptDanger(out, ad, ciphertext []byte, n uint64, nb []byte) ([]byte, error) {
  41. if s != nil {
  42. nb[0] = 0
  43. nb[1] = 0
  44. nb[2] = 0
  45. nb[3] = 0
  46. noiseEndianness.PutUint64(nb[4:], n)
  47. return s.c.(cipher.AEAD).Open(out, nb, ciphertext, ad)
  48. } else {
  49. return []byte{}, nil
  50. }
  51. }