Skip to content

Commit

Permalink
remove deprecate ciphers in shadowsocks (v2fly#566)
Browse files Browse the repository at this point in the history
* remove deprecate ciphers in shadowsocks
  • Loading branch information
kslr authored Jan 1, 2021
1 parent b10108b commit 42f0f5d
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 543 deletions.
8 changes: 0 additions & 8 deletions infra/conf/shadowsocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ import (

func cipherFromString(c string) shadowsocks.CipherType {
switch strings.ToLower(c) {
case "aes-256-cfb":
return shadowsocks.CipherType_AES_256_CFB
case "aes-128-cfb":
return shadowsocks.CipherType_AES_128_CFB
case "chacha20":
return shadowsocks.CipherType_CHACHA20
case "chacha20-ietf":
return shadowsocks.CipherType_CHACHA20_IETF
case "aes-128-gcm", "aead_aes_128_gcm":
return shadowsocks.CipherType_AES_128_GCM
case "aes-256-gcm", "aead_aes_256_gcm":
Expand Down
4 changes: 2 additions & 2 deletions infra/conf/shadowsocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ func TestShadowsocksServerConfigParsing(t *testing.T) {
runMultiTestCase(t, []TestCase{
{
Input: `{
"method": "aes-128-cfb",
"method": "aes-256-GCM",
"password": "v2ray-password"
}`,
Parser: loadJSON(creator),
Output: &shadowsocks.ServerConfig{
User: &protocol.User{
Account: serial.ToTypedMessage(&shadowsocks.Account{
CipherType: shadowsocks.CipherType_AES_128_CFB,
CipherType: shadowsocks.CipherType_AES_256_GCM,
Password: "v2ray-password",
}),
},
Expand Down
119 changes: 10 additions & 109 deletions proxy/shadowsocks/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,14 @@ func createAesGcm(key []byte) cipher.AEAD {
return gcm
}

func createChacha20Poly1305(key []byte) cipher.AEAD {
chacha20, err := chacha20poly1305.New(key)
func createChaCha20Poly1305(key []byte) cipher.AEAD {
ChaChaPoly1305, err := chacha20poly1305.New(key)
common.Must(err)
return chacha20
return ChaChaPoly1305
}

func (a *Account) getCipher() (Cipher, error) {
switch a.CipherType {
case CipherType_AES_128_CFB:
return &AesCfb{KeyBytes: 16}, nil
case CipherType_AES_256_CFB:
return &AesCfb{KeyBytes: 32}, nil
case CipherType_CHACHA20:
return &ChaCha20{IVBytes: 8}, nil
case CipherType_CHACHA20_IETF:
return &ChaCha20{IVBytes: 12}, nil
case CipherType_AES_128_GCM:
return &AEADCipher{
KeyBytes: 16,
Expand All @@ -71,7 +63,7 @@ func (a *Account) getCipher() (Cipher, error) {
return &AEADCipher{
KeyBytes: 32,
IVBytes: 32,
AEADAuthCreator: createChacha20Poly1305,
AEADAuthCreator: createChaCha20Poly1305,
}, nil
case CipherType_NONE:
return NoneCipher{}, nil
Expand All @@ -82,13 +74,13 @@ func (a *Account) getCipher() (Cipher, error) {

// AsAccount implements protocol.AsAccount.
func (a *Account) AsAccount() (protocol.Account, error) {
cipher, err := a.getCipher()
Cipher, err := a.getCipher()
if err != nil {
return nil, newError("failed to get cipher").Base(err)
}
return &MemoryAccount{
Cipher: cipher,
Key: passwordToCipherKey([]byte(a.Password), cipher.KeySize()),
Cipher: Cipher,
Key: passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),
}, nil
}

Expand All @@ -103,53 +95,6 @@ type Cipher interface {
DecodePacket(key []byte, b *buf.Buffer) error
}

// AesCfb represents all AES-CFB ciphers.
type AesCfb struct {
KeyBytes int32
}

func (*AesCfb) IsAEAD() bool {
return false
}

func (v *AesCfb) KeySize() int32 {
return v.KeyBytes
}

func (v *AesCfb) IVSize() int32 {
return 16
}

func (v *AesCfb) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
stream := crypto.NewAesEncryptionStream(key, iv)
return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil
}

func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
stream := crypto.NewAesDecryptionStream(key, iv)
return &buf.SingleReader{
Reader: crypto.NewCryptionReader(stream, reader),
}, nil
}

func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error {
iv := b.BytesTo(v.IVSize())
stream := crypto.NewAesEncryptionStream(key, iv)
stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
return nil
}

func (v *AesCfb) DecodePacket(key []byte, b *buf.Buffer) error {
if b.Len() <= v.IVSize() {
return newError("insufficient data: ", b.Len())
}
iv := b.BytesTo(v.IVSize())
stream := crypto.NewAesDecryptionStream(key, iv)
stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
b.Advance(v.IVSize())
return nil
}

type AEADCipher struct {
KeyBytes int32
IVBytes int32
Expand Down Expand Up @@ -218,56 +163,12 @@ func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
return nil
}

type ChaCha20 struct {
IVBytes int32
}

func (*ChaCha20) IsAEAD() bool {
return false
}

func (v *ChaCha20) KeySize() int32 {
return 32
}

func (v *ChaCha20) IVSize() int32 {
return v.IVBytes
}

func (v *ChaCha20) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
stream := crypto.NewChaCha20Stream(key, iv)
return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil
}

func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
stream := crypto.NewChaCha20Stream(key, iv)
return &buf.SingleReader{Reader: crypto.NewCryptionReader(stream, reader)}, nil
}

func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error {
iv := b.BytesTo(v.IVSize())
stream := crypto.NewChaCha20Stream(key, iv)
stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
return nil
}

func (v *ChaCha20) DecodePacket(key []byte, b *buf.Buffer) error {
if b.Len() <= v.IVSize() {
return newError("insufficient data: ", b.Len())
}
iv := b.BytesTo(v.IVSize())
stream := crypto.NewChaCha20Stream(key, iv)
stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
b.Advance(v.IVSize())
return nil
}

type NoneCipher struct{}

func (NoneCipher) KeySize() int32 { return 0 }
func (NoneCipher) IVSize() int32 { return 0 }
func (NoneCipher) IsAEAD() bool {
return true // to avoid OTA
return false
}

func (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
Expand Down Expand Up @@ -303,7 +204,7 @@ func passwordToCipherKey(password []byte, keySize int32) []byte {
return key
}

func hkdfSHA1(secret, salt, outkey []byte) {
func hkdfSHA1(secret, salt, outKey []byte) {
r := hkdf.New(sha1.New, secret, salt, []byte("ss-subkey"))
common.Must2(io.ReadFull(r, outkey))
common.Must2(io.ReadFull(r, outKey))
}
69 changes: 26 additions & 43 deletions proxy/shadowsocks/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions proxy/shadowsocks/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ message Account {

enum CipherType {
UNKNOWN = 0;
AES_128_CFB = 1;
AES_256_CFB = 2;
CHACHA20 = 3;
CHACHA20_IETF = 4;
AES_128_GCM = 5;
AES_256_GCM = 6;
CHACHA20_POLY1305 = 7;
NONE = 8;
AES_128_GCM = 1;
AES_256_GCM = 2;
CHACHA20_POLY1305 = 3;
NONE = 4;
}

message ServerConfig {
Expand Down
Loading

0 comments on commit 42f0f5d

Please sign in to comment.