crypt.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. len := buffer.Len()
  31. xtra := 4 - len%4
  32. if xtra != 0 {
  33. buffer.Slice(0, len+xtra)
  34. }
  35. xorfwd(buffer.Value)
  36. if xtra != 0 {
  37. buffer.Slice(0, len)
  38. }
  39. }
  40. func (this *SimpleAuthenticator) Open(buffer *alloc.Buffer) bool {
  41. len := buffer.Len()
  42. xtra := 4 - len%4
  43. if xtra != 0 {
  44. buffer.Slice(0, len+xtra)
  45. }
  46. xorbkd(buffer.Value)
  47. if xtra != 0 {
  48. buffer.Slice(0, len)
  49. }
  50. fnvHash := fnv.New32a()
  51. fnvHash.Write(buffer.Value[4:])
  52. if serial.BytesToUint32(buffer.Value[:4]) != fnvHash.Sum32() {
  53. return false
  54. }
  55. length := serial.BytesToUint16(buffer.Value[4:6])
  56. if buffer.Len()-6 != int(length) {
  57. return false
  58. }
  59. buffer.SliceFrom(6)
  60. return true
  61. }