github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/shadowsocks/config.go (about) 1 package shadowsocks 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/md5" 8 "crypto/sha1" 9 "io" 10 11 "golang.org/x/crypto/chacha20poly1305" 12 "golang.org/x/crypto/hkdf" 13 14 "v2ray.com/core/common" 15 "v2ray.com/core/common/buf" 16 "v2ray.com/core/common/crypto" 17 "v2ray.com/core/common/protocol" 18 ) 19 20 // MemoryAccount is an account type converted from Account. 21 type MemoryAccount struct { 22 Cipher Cipher 23 Key []byte 24 } 25 26 // Equals implements protocol.Account.Equals(). 27 func (a *MemoryAccount) Equals(another protocol.Account) bool { 28 if account, ok := another.(*MemoryAccount); ok { 29 return bytes.Equal(a.Key, account.Key) 30 } 31 return false 32 } 33 34 func createAesGcm(key []byte) cipher.AEAD { 35 block, err := aes.NewCipher(key) 36 common.Must(err) 37 gcm, err := cipher.NewGCM(block) 38 common.Must(err) 39 return gcm 40 } 41 42 func createChacha20Poly1305(key []byte) cipher.AEAD { 43 chacha20, err := chacha20poly1305.New(key) 44 common.Must(err) 45 return chacha20 46 } 47 48 func (a *Account) getCipher() (Cipher, error) { 49 switch a.CipherType { 50 case CipherType_AES_128_CFB: 51 return &AesCfb{KeyBytes: 16}, nil 52 case CipherType_AES_256_CFB: 53 return &AesCfb{KeyBytes: 32}, nil 54 case CipherType_CHACHA20: 55 return &ChaCha20{IVBytes: 8}, nil 56 case CipherType_CHACHA20_IETF: 57 return &ChaCha20{IVBytes: 12}, nil 58 case CipherType_AES_128_GCM: 59 return &AEADCipher{ 60 KeyBytes: 16, 61 IVBytes: 16, 62 AEADAuthCreator: createAesGcm, 63 }, nil 64 case CipherType_AES_256_GCM: 65 return &AEADCipher{ 66 KeyBytes: 32, 67 IVBytes: 32, 68 AEADAuthCreator: createAesGcm, 69 }, nil 70 case CipherType_CHACHA20_POLY1305: 71 return &AEADCipher{ 72 KeyBytes: 32, 73 IVBytes: 32, 74 AEADAuthCreator: createChacha20Poly1305, 75 }, nil 76 case CipherType_NONE: 77 return NoneCipher{}, nil 78 default: 79 return nil, newError("Unsupported cipher.") 80 } 81 } 82 83 // AsAccount implements protocol.AsAccount. 84 func (a *Account) AsAccount() (protocol.Account, error) { 85 cipher, err := a.getCipher() 86 if err != nil { 87 return nil, newError("failed to get cipher").Base(err) 88 } 89 return &MemoryAccount{ 90 Cipher: cipher, 91 Key: passwordToCipherKey([]byte(a.Password), cipher.KeySize()), 92 }, nil 93 } 94 95 // Cipher is an interface for all Shadowsocks ciphers. 96 type Cipher interface { 97 KeySize() int32 98 IVSize() int32 99 NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) 100 NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) 101 IsAEAD() bool 102 EncodePacket(key []byte, b *buf.Buffer) error 103 DecodePacket(key []byte, b *buf.Buffer) error 104 } 105 106 // AesCfb represents all AES-CFB ciphers. 107 type AesCfb struct { 108 KeyBytes int32 109 } 110 111 func (*AesCfb) IsAEAD() bool { 112 return false 113 } 114 115 func (v *AesCfb) KeySize() int32 { 116 return v.KeyBytes 117 } 118 119 func (v *AesCfb) IVSize() int32 { 120 return 16 121 } 122 123 func (v *AesCfb) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { 124 stream := crypto.NewAesEncryptionStream(key, iv) 125 return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil 126 } 127 128 func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { 129 stream := crypto.NewAesDecryptionStream(key, iv) 130 return &buf.SingleReader{ 131 Reader: crypto.NewCryptionReader(stream, reader), 132 }, nil 133 } 134 135 func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error { 136 iv := b.BytesTo(v.IVSize()) 137 stream := crypto.NewAesEncryptionStream(key, iv) 138 stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) 139 return nil 140 } 141 142 func (v *AesCfb) DecodePacket(key []byte, b *buf.Buffer) error { 143 if b.Len() <= v.IVSize() { 144 return newError("insufficient data: ", b.Len()) 145 } 146 iv := b.BytesTo(v.IVSize()) 147 stream := crypto.NewAesDecryptionStream(key, iv) 148 stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) 149 b.Advance(v.IVSize()) 150 return nil 151 } 152 153 type AEADCipher struct { 154 KeyBytes int32 155 IVBytes int32 156 AEADAuthCreator func(key []byte) cipher.AEAD 157 } 158 159 func (*AEADCipher) IsAEAD() bool { 160 return true 161 } 162 163 func (c *AEADCipher) KeySize() int32 { 164 return c.KeyBytes 165 } 166 167 func (c *AEADCipher) IVSize() int32 { 168 return c.IVBytes 169 } 170 171 func (c *AEADCipher) createAuthenticator(key []byte, iv []byte) *crypto.AEADAuthenticator { 172 nonce := crypto.GenerateInitialAEADNonce() 173 subkey := make([]byte, c.KeyBytes) 174 hkdfSHA1(key, iv, subkey) 175 return &crypto.AEADAuthenticator{ 176 AEAD: c.AEADAuthCreator(subkey), 177 NonceGenerator: nonce, 178 } 179 } 180 181 func (c *AEADCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { 182 auth := c.createAuthenticator(key, iv) 183 return crypto.NewAuthenticationWriter(auth, &crypto.AEADChunkSizeParser{ 184 Auth: auth, 185 }, writer, protocol.TransferTypeStream, nil), nil 186 } 187 188 func (c *AEADCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { 189 auth := c.createAuthenticator(key, iv) 190 return crypto.NewAuthenticationReader(auth, &crypto.AEADChunkSizeParser{ 191 Auth: auth, 192 }, reader, protocol.TransferTypeStream, nil), nil 193 } 194 195 func (c *AEADCipher) EncodePacket(key []byte, b *buf.Buffer) error { 196 ivLen := c.IVSize() 197 payloadLen := b.Len() 198 auth := c.createAuthenticator(key, b.BytesTo(ivLen)) 199 200 b.Extend(int32(auth.Overhead())) 201 _, err := auth.Seal(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen)) 202 return err 203 } 204 205 func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error { 206 if b.Len() <= c.IVSize() { 207 return newError("insufficient data: ", b.Len()) 208 } 209 ivLen := c.IVSize() 210 payloadLen := b.Len() 211 auth := c.createAuthenticator(key, b.BytesTo(ivLen)) 212 213 bbb, err := auth.Open(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen)) 214 if err != nil { 215 return err 216 } 217 b.Resize(ivLen, int32(len(bbb))) 218 return nil 219 } 220 221 type ChaCha20 struct { 222 IVBytes int32 223 } 224 225 func (*ChaCha20) IsAEAD() bool { 226 return false 227 } 228 229 func (v *ChaCha20) KeySize() int32 { 230 return 32 231 } 232 233 func (v *ChaCha20) IVSize() int32 { 234 return v.IVBytes 235 } 236 237 func (v *ChaCha20) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { 238 stream := crypto.NewChaCha20Stream(key, iv) 239 return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil 240 } 241 242 func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { 243 stream := crypto.NewChaCha20Stream(key, iv) 244 return &buf.SingleReader{Reader: crypto.NewCryptionReader(stream, reader)}, nil 245 } 246 247 func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error { 248 iv := b.BytesTo(v.IVSize()) 249 stream := crypto.NewChaCha20Stream(key, iv) 250 stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) 251 return nil 252 } 253 254 func (v *ChaCha20) DecodePacket(key []byte, b *buf.Buffer) error { 255 if b.Len() <= v.IVSize() { 256 return newError("insufficient data: ", b.Len()) 257 } 258 iv := b.BytesTo(v.IVSize()) 259 stream := crypto.NewChaCha20Stream(key, iv) 260 stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) 261 b.Advance(v.IVSize()) 262 return nil 263 } 264 265 type NoneCipher struct{} 266 267 func (NoneCipher) KeySize() int32 { return 0 } 268 func (NoneCipher) IVSize() int32 { return 0 } 269 func (NoneCipher) IsAEAD() bool { 270 return true // to avoid OTA 271 } 272 273 func (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { 274 return buf.NewReader(reader), nil 275 } 276 277 func (NoneCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { 278 return buf.NewWriter(writer), nil 279 } 280 281 func (NoneCipher) EncodePacket(key []byte, b *buf.Buffer) error { 282 return nil 283 } 284 285 func (NoneCipher) DecodePacket(key []byte, b *buf.Buffer) error { 286 return nil 287 } 288 289 func passwordToCipherKey(password []byte, keySize int32) []byte { 290 key := make([]byte, 0, keySize) 291 292 md5Sum := md5.Sum(password) 293 key = append(key, md5Sum[:]...) 294 295 for int32(len(key)) < keySize { 296 md5Hash := md5.New() 297 common.Must2(md5Hash.Write(md5Sum[:])) 298 common.Must2(md5Hash.Write(password)) 299 md5Hash.Sum(md5Sum[:0]) 300 301 key = append(key, md5Sum[:]...) 302 } 303 return key 304 } 305 306 func hkdfSHA1(secret, salt, outkey []byte) { 307 r := hkdf.New(sha1.New, secret, salt, []byte("ss-subkey")) 308 common.Must2(io.ReadFull(r, outkey)) 309 }