crypt.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package kcp
  2. import (
  3. "hash/fnv"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. "github.com/v2ray/v2ray-core/common/serial"
  6. )
  7. type Authenticator interface {
  8. HeaderSize() int
  9. // Encrypt encrypts the whole block in src into dst.
  10. // Dst and src may point at the same memory.
  11. Seal(buffer *alloc.Buffer)
  12. // Decrypt decrypts the whole block in src into dst.
  13. // Dst and src may point at the same memory.
  14. Open(buffer *alloc.Buffer) bool
  15. }
  16. type SimpleAuthenticator struct{}
  17. func NewSimpleAuthenticator() Authenticator {
  18. return &SimpleAuthenticator{}
  19. }
  20. func (this *SimpleAuthenticator) HeaderSize() int {
  21. return 6
  22. }
  23. func (this *SimpleAuthenticator) Seal(buffer *alloc.Buffer) {
  24. var length uint16 = uint16(buffer.Len())
  25. buffer.Prepend(serial.Uint16ToBytes(length))
  26. fnvHash := fnv.New32a()
  27. fnvHash.Write(buffer.Value)
  28. buffer.SliceBack(4)
  29. fnvHash.Sum(buffer.Value[:0])
  30. for i := 4; i < buffer.Len(); i++ {
  31. buffer.Value[i] ^= buffer.Value[i-4]
  32. }
  33. }
  34. func (this *SimpleAuthenticator) Open(buffer *alloc.Buffer) bool {
  35. for i := buffer.Len() - 1; i >= 4; i-- {
  36. buffer.Value[i] ^= buffer.Value[i-4]
  37. }
  38. fnvHash := fnv.New32a()
  39. fnvHash.Write(buffer.Value[4:])
  40. if serial.BytesToUint32(buffer.Value[:4]) != fnvHash.Sum32() {
  41. return false
  42. }
  43. length := serial.BytesToUint16(buffer.Value[4:6])
  44. if buffer.Len()-6 != int(length) {
  45. return false
  46. }
  47. buffer.SliceFrom(6)
  48. return true
  49. }