github.com/v2fly/v2ray-core/v4@v4.45.2/transport/internet/kcp/crypt.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package kcp 5 6 import ( 7 "crypto/cipher" 8 "encoding/binary" 9 "hash/fnv" 10 11 "github.com/v2fly/v2ray-core/v4/common" 12 ) 13 14 // SimpleAuthenticator is a legacy AEAD used for KCP encryption. 15 type SimpleAuthenticator struct{} 16 17 // NewSimpleAuthenticator creates a new SimpleAuthenticator 18 func NewSimpleAuthenticator() cipher.AEAD { 19 return &SimpleAuthenticator{} 20 } 21 22 // NonceSize implements cipher.AEAD.NonceSize(). 23 func (*SimpleAuthenticator) NonceSize() int { 24 return 0 25 } 26 27 // Overhead implements cipher.AEAD.NonceSize(). 28 func (*SimpleAuthenticator) Overhead() int { 29 return 6 30 } 31 32 // Seal implements cipher.AEAD.Seal(). 33 func (a *SimpleAuthenticator) Seal(dst, nonce, plain, extra []byte) []byte { 34 dst = append(dst, 0, 0, 0, 0, 0, 0) // 4 bytes for hash, and then 2 bytes for length 35 binary.BigEndian.PutUint16(dst[4:], uint16(len(plain))) 36 dst = append(dst, plain...) 37 38 fnvHash := fnv.New32a() 39 common.Must2(fnvHash.Write(dst[4:])) 40 fnvHash.Sum(dst[:0]) 41 42 dstLen := len(dst) 43 xtra := 4 - dstLen%4 44 if xtra != 4 { 45 dst = append(dst, make([]byte, xtra)...) 46 } 47 xorfwd(dst) 48 if xtra != 4 { 49 dst = dst[:dstLen] 50 } 51 return dst 52 } 53 54 // Open implements cipher.AEAD.Open(). 55 func (a *SimpleAuthenticator) Open(dst, nonce, cipherText, extra []byte) ([]byte, error) { 56 dst = append(dst, cipherText...) 57 dstLen := len(dst) 58 xtra := 4 - dstLen%4 59 if xtra != 4 { 60 dst = append(dst, make([]byte, xtra)...) 61 } 62 xorbkd(dst) 63 if xtra != 4 { 64 dst = dst[:dstLen] 65 } 66 67 fnvHash := fnv.New32a() 68 common.Must2(fnvHash.Write(dst[4:])) 69 if binary.BigEndian.Uint32(dst[:4]) != fnvHash.Sum32() { 70 return nil, newError("invalid auth") 71 } 72 73 length := binary.BigEndian.Uint16(dst[4:6]) 74 if len(dst)-6 != int(length) { 75 return nil, newError("invalid auth") 76 } 77 78 return dst[6:], nil 79 }