package kcp import ( "crypto/aes" "crypto/cipher" "crypto/des" "crypto/sha1" "github.com/templexxx/xor" "github.com/tjfoc/gmsm/sm4" "golang.org/x/crypto/blowfish" "golang.org/x/crypto/cast5" "golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/salsa20" "golang.org/x/crypto/tea" "golang.org/x/crypto/twofish" "golang.org/x/crypto/xtea" ) var ( initialVector = []byte{167, 115, 79, 156, 18, 172, 27, 1, 164, 21, 242, 193, 252, 120, 230, 107} saltxor = `sH3CIVoF#rWLtJo6` ) // BlockCrypt defines encryption/decryption methods for a given byte slice. // Notes on implementing: the data to be encrypted contains a builtin // nonce at the first 16 bytes type BlockCrypt interface { // Encrypt encrypts the whole block in src into dst. // Dst and src may point at the same memory. Encrypt(dst, src []byte) // Decrypt decrypts the whole block in src into dst. // Dst and src may point at the same memory. Decrypt(dst, src []byte) } type salsa20BlockCrypt struct { key [32]byte } // NewSalsa20BlockCrypt https://en.wikipedia.org/wiki/Salsa20 func NewSalsa20BlockCrypt(key []byte) (BlockCrypt, error) { c := new(salsa20BlockCrypt) copy(c.key[:], key) return c, nil } func (c *salsa20BlockCrypt) Encrypt(dst, src []byte) { salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key) copy(dst[:8], src[:8]) } func (c *salsa20BlockCrypt) Decrypt(dst, src []byte) { salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key) copy(dst[:8], src[:8]) } type sm4BlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewSM4BlockCrypt https://github.com/tjfoc/gmsm/tree/master/sm4 func NewSM4BlockCrypt(key []byte) (BlockCrypt, error) { c := new(sm4BlockCrypt) block, err := sm4.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, sm4.BlockSize) c.decbuf = make([]byte, 2*sm4.BlockSize) return c, nil } func (c *sm4BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *sm4BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type twofishBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewTwofishBlockCrypt https://en.wikipedia.org/wiki/Twofish func NewTwofishBlockCrypt(key []byte) (BlockCrypt, error) { c := new(twofishBlockCrypt) block, err := twofish.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, twofish.BlockSize) c.decbuf = make([]byte, 2*twofish.BlockSize) return c, nil } func (c *twofishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *twofishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type tripleDESBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewTripleDESBlockCrypt https://en.wikipedia.org/wiki/Triple_DES func NewTripleDESBlockCrypt(key []byte) (BlockCrypt, error) { c := new(tripleDESBlockCrypt) block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, des.BlockSize) c.decbuf = make([]byte, 2*des.BlockSize) return c, nil } func (c *tripleDESBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *tripleDESBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type cast5BlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewCast5BlockCrypt https://en.wikipedia.org/wiki/CAST-128 func NewCast5BlockCrypt(key []byte) (BlockCrypt, error) { c := new(cast5BlockCrypt) block, err := cast5.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, cast5.BlockSize) c.decbuf = make([]byte, 2*cast5.BlockSize) return c, nil } func (c *cast5BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *cast5BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type blowfishBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewBlowfishBlockCrypt https://en.wikipedia.org/wiki/Blowfish_(cipher) func NewBlowfishBlockCrypt(key []byte) (BlockCrypt, error) { c := new(blowfishBlockCrypt) block, err := blowfish.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, blowfish.BlockSize) c.decbuf = make([]byte, 2*blowfish.BlockSize) return c, nil } func (c *blowfishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *blowfishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type aesBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewAESBlockCrypt https://en.wikipedia.org/wiki/Advanced_Encryption_Standard func NewAESBlockCrypt(key []byte) (BlockCrypt, error) { c := new(aesBlockCrypt) block, err := aes.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, aes.BlockSize) c.decbuf = make([]byte, 2*aes.BlockSize) return c, nil } func (c *aesBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *aesBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type teaBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewTEABlockCrypt https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm func NewTEABlockCrypt(key []byte) (BlockCrypt, error) { c := new(teaBlockCrypt) block, err := tea.NewCipherWithRounds(key, 16) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, tea.BlockSize) c.decbuf = make([]byte, 2*tea.BlockSize) return c, nil } func (c *teaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *teaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type xteaBlockCrypt struct { encbuf []byte decbuf []byte block cipher.Block } // NewXTEABlockCrypt https://en.wikipedia.org/wiki/XTEA func NewXTEABlockCrypt(key []byte) (BlockCrypt, error) { c := new(xteaBlockCrypt) block, err := xtea.NewCipher(key) if err != nil { return nil, err } c.block = block c.encbuf = make([]byte, xtea.BlockSize) c.decbuf = make([]byte, 2*xtea.BlockSize) return c, nil } func (c *xteaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf) } func (c *xteaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf) } type simpleXORBlockCrypt struct { xortbl []byte } // NewSimpleXORBlockCrypt simple xor with key expanding func NewSimpleXORBlockCrypt(key []byte) (BlockCrypt, error) { c := new(simpleXORBlockCrypt) c.xortbl = pbkdf2.Key(key, []byte(saltxor), 32, mtuLimit, sha1.New) return c, nil } func (c *simpleXORBlockCrypt) Encrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) } func (c *simpleXORBlockCrypt) Decrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) } type noneBlockCrypt struct{} // NewNoneBlockCrypt does nothing but copying func NewNoneBlockCrypt(key []byte) (BlockCrypt, error) { return new(noneBlockCrypt), nil } func (c *noneBlockCrypt) Encrypt(dst, src []byte) { copy(dst, src) } func (c *noneBlockCrypt) Decrypt(dst, src []byte) { copy(dst, src) } // packet encryption with local CFB mode func encrypt(block cipher.Block, dst, src, buf []byte) { blocksize := block.BlockSize() tbl := buf[:blocksize] block.Encrypt(tbl, initialVector) n := len(src) / blocksize base := 0 for i := 0; i < n; i++ { xor.BytesSrc1(dst[base:], src[base:], tbl) block.Encrypt(tbl, dst[base:]) base += blocksize } xor.BytesSrc0(dst[base:], src[base:], tbl) } func decrypt(block cipher.Block, dst, src, buf []byte) { blocksize := block.BlockSize() tbl := buf[:blocksize] next := buf[blocksize:] block.Encrypt(tbl, initialVector) n := len(src) / blocksize base := 0 for i := 0; i < n; i++ { block.Encrypt(next, src[base:]) xor.BytesSrc1(dst[base:], src[base:], tbl) tbl, next = next, tbl base += blocksize } xor.BytesSrc0(dst[base:], src[base:], tbl) }