Add new encryption method option aes-128-gcm

This commit is contained in:
Andy Wang 2020-12-27 13:26:45 +00:00
parent cbd71fae6d
commit d1b05ee9e5
No known key found for this signature in database
GPG Key ID: 181B49F9F38F3374
8 changed files with 50 additions and 17 deletions

View File

@ -126,11 +126,11 @@ instead a CDN is used, use `CDN`.
`ProxyMethod` is the name of the proxy method you are using. This must match one of the entries in the `ProxyMethod` is the name of the proxy method you are using. This must match one of the entries in the
server's `ProxyBook` exactly. server's `ProxyBook` exactly.
`EncryptionMethod` is the name of the encryption algorithm you want Cloak to use. Options are `plain`, `aes-gcm` `EncryptionMethod` is the name of the encryption algorithm you want Cloak to use. Options are `plain`, `aes-256-gcm` (
and `chacha20-poly1305`. Note: Cloak isn't intended to provide transport security. The point of encryption is to hide synonymous to `aes-gcm`), `aes-128-gcm`, and `chacha20-poly1305`. Note: Cloak isn't intended to provide transport
fingerprints of proxy protocols and render the payload statistically random-like. **You may only leave it as `plain` if security. The point of encryption is to hide fingerprints of proxy protocols and render the payload statistically
you are certain that your underlying proxy tool already provides BOTH encryption and authentication (via AEAD or similar random-like. **You may only leave it as `plain` if you are certain that your underlying proxy tool already provides BOTH
techniques).** encryption and authentication (via AEAD or similar techniques).**
`ServerName` is the domain you want to make your ISP or firewall _think_ you are visiting. Ideally it should `ServerName` is the domain you want to make your ISP or firewall _think_ you are visiting. Ideally it should
match `RedirAddr` in the server's configuration, a major site the censor allows, but it doesn't have to. match `RedirAddr` in the server's configuration, a major site the censor allows, but it doesn't have to.

View File

@ -164,7 +164,10 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca
case "plain": case "plain":
auth.EncryptionMethod = mux.EncryptionMethodPlain auth.EncryptionMethod = mux.EncryptionMethodPlain
case "aes-gcm": case "aes-gcm":
auth.EncryptionMethod = mux.EncryptionMethodAESGCM case "aes-256-gcm":
auth.EncryptionMethod = mux.EncryptionMethodAES256GCM
case "aes-128-gcm":
auth.EncryptionMethod = mux.EncryptionMethodAES128GCM
case "chacha20-poly1305": case "chacha20-poly1305":
auth.EncryptionMethod = mux.EncryptionMethodChaha20Poly1305 auth.EncryptionMethod = mux.EncryptionMethodChaha20Poly1305
default: default:

View File

@ -21,8 +21,9 @@ const salsa20NonceSize = 8
const ( const (
EncryptionMethodPlain = iota EncryptionMethodPlain = iota
EncryptionMethodAESGCM EncryptionMethodAES256GCM
EncryptionMethodChaha20Poly1305 EncryptionMethodChaha20Poly1305
EncryptionMethodAES128GCM
) )
// Obfuscator is responsible for serialisation, obfuscation, and optional encryption of data frames. // Obfuscator is responsible for serialisation, obfuscation, and optional encryption of data frames.
@ -171,7 +172,7 @@ func MakeObfuscator(encryptionMethod byte, sessionKey [32]byte) (obfuscator Obfu
case EncryptionMethodPlain: case EncryptionMethodPlain:
payloadCipher = nil payloadCipher = nil
obfuscator.maxOverhead = salsa20NonceSize obfuscator.maxOverhead = salsa20NonceSize
case EncryptionMethodAESGCM: case EncryptionMethodAES256GCM:
var c cipher.Block var c cipher.Block
c, err = aes.NewCipher(sessionKey[:]) c, err = aes.NewCipher(sessionKey[:])
if err != nil { if err != nil {
@ -182,6 +183,17 @@ func MakeObfuscator(encryptionMethod byte, sessionKey [32]byte) (obfuscator Obfu
return return
} }
obfuscator.maxOverhead = payloadCipher.Overhead() obfuscator.maxOverhead = payloadCipher.Overhead()
case EncryptionMethodAES128GCM:
var c cipher.Block
c, err = aes.NewCipher(sessionKey[:16])
if err != nil {
return
}
payloadCipher, err = cipher.NewGCM(c)
if err != nil {
return
}
obfuscator.maxOverhead = payloadCipher.Overhead()
case EncryptionMethodChaha20Poly1305: case EncryptionMethodChaha20Poly1305:
payloadCipher, err = chacha20poly1305.New(sessionKey[:]) payloadCipher, err = chacha20poly1305.New(sessionKey[:])
if err != nil { if err != nil {
@ -189,7 +201,7 @@ func MakeObfuscator(encryptionMethod byte, sessionKey [32]byte) (obfuscator Obfu
} }
obfuscator.maxOverhead = payloadCipher.Overhead() obfuscator.maxOverhead = payloadCipher.Overhead()
default: default:
return obfuscator, errors.New("Unknown encryption method") return obfuscator, fmt.Errorf("unknown encryption method valued %v", encryptionMethod)
} }
if payloadCipher != nil { if payloadCipher != nil {

View File

@ -46,8 +46,16 @@ func TestGenerateObfs(t *testing.T) {
run(obfuscator, t) run(obfuscator, t)
} }
}) })
t.Run("aes-gcm", func(t *testing.T) { t.Run("aes-256-gcm", func(t *testing.T) {
obfuscator, err := MakeObfuscator(EncryptionMethodAESGCM, sessionKey) obfuscator, err := MakeObfuscator(EncryptionMethodAES256GCM, sessionKey)
if err != nil {
t.Errorf("failed to generate obfuscator %v", err)
} else {
run(obfuscator, t)
}
})
t.Run("aes-128-gcm", func(t *testing.T) {
obfuscator, err := MakeObfuscator(EncryptionMethodAES128GCM, sessionKey)
if err != nil { if err != nil {
t.Errorf("failed to generate obfuscator %v", err) t.Errorf("failed to generate obfuscator %v", err)
} else { } else {

View File

@ -44,7 +44,7 @@ func TestRecvDataFromRemote(t *testing.T) {
encryptionMethods := map[string]Obfuscator{ encryptionMethods := map[string]Obfuscator{
"plain": MakeObfuscatorUnwrap(EncryptionMethodPlain, sessionKey), "plain": MakeObfuscatorUnwrap(EncryptionMethodPlain, sessionKey),
"aes-gcm": MakeObfuscatorUnwrap(EncryptionMethodAESGCM, sessionKey), "aes-gcm": MakeObfuscatorUnwrap(EncryptionMethodAES256GCM, sessionKey),
"chacha20-poly1305": MakeObfuscatorUnwrap(EncryptionMethodChaha20Poly1305, sessionKey), "chacha20-poly1305": MakeObfuscatorUnwrap(EncryptionMethodChaha20Poly1305, sessionKey),
} }
@ -430,7 +430,8 @@ func BenchmarkRecvDataFromRemote_Ordered(b *testing.B) {
table := map[string]byte{ table := map[string]byte{
"plain": EncryptionMethodPlain, "plain": EncryptionMethodPlain,
"aes-gcm": EncryptionMethodAESGCM, "aes-256-gcm": EncryptionMethodAES256GCM,
"aes-128-gcm": EncryptionMethodAES128GCM,
"chacha20poly1305": EncryptionMethodChaha20Poly1305, "chacha20poly1305": EncryptionMethodChaha20Poly1305,
} }
@ -466,7 +467,8 @@ func BenchmarkMultiStreamWrite(b *testing.B) {
table := map[string]byte{ table := map[string]byte{
"plain": EncryptionMethodPlain, "plain": EncryptionMethodPlain,
"aes-gcm": EncryptionMethodAESGCM, "aes-256-gcm": EncryptionMethodAES256GCM,
"aes-128-gcm": EncryptionMethodAES128GCM,
"chacha20poly1305": EncryptionMethodChaha20Poly1305, "chacha20poly1305": EncryptionMethodChaha20Poly1305,
} }

View File

@ -39,7 +39,8 @@ func BenchmarkStream_Write_Ordered(b *testing.B) {
eMethods := map[string]byte{ eMethods := map[string]byte{
"plain": EncryptionMethodPlain, "plain": EncryptionMethodPlain,
"chacha20-poly1305": EncryptionMethodChaha20Poly1305, "chacha20-poly1305": EncryptionMethodChaha20Poly1305,
"aes-gcm": EncryptionMethodAESGCM, "aes-256-gcm": EncryptionMethodAES256GCM,
"aes-128-gcm": EncryptionMethodAES128GCM,
} }
for name, method := range eMethods { for name, method := range eMethods {

View File

@ -175,7 +175,13 @@ func dispatchConnection(conn net.Conn, sta *State) {
common.RandRead(sta.WorldState.Rand, sessionKey[:]) common.RandRead(sta.WorldState.Rand, sessionKey[:])
obfuscator, err := mux.MakeObfuscator(ci.EncryptionMethod, sessionKey) obfuscator, err := mux.MakeObfuscator(ci.EncryptionMethod, sessionKey)
if err != nil { if err != nil {
log.Error(err) log.WithFields(log.Fields{
"remoteAddr": conn.RemoteAddr(),
"UID": b64(ci.UID),
"sessionId": ci.SessionId,
"proxyMethod": ci.ProxyMethod,
"encryptionMethod": ci.EncryptionMethod,
}).Error(err)
goWeb() goWeb()
return return
} }

View File

@ -518,7 +518,8 @@ func BenchmarkIntegration(b *testing.B) {
encryptionMethods := map[string]byte{ encryptionMethods := map[string]byte{
"plain": mux.EncryptionMethodPlain, "plain": mux.EncryptionMethodPlain,
"chacha20-poly1305": mux.EncryptionMethodChaha20Poly1305, "chacha20-poly1305": mux.EncryptionMethodChaha20Poly1305,
"aes-gcm": mux.EncryptionMethodAESGCM, "aes-256-gcm": mux.EncryptionMethodAES256GCM,
"aes-128-gcm": mux.EncryptionMethodAES128GCM,
} }
for name, method := range encryptionMethods { for name, method := range encryptionMethods {