crypt.go 1.5 KB

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