Shadowsocks documentation

AEAD

AEAD stands for Authenticated Encryption with Associated Data. AEAD ciphers simultaneously provide confidentiality, integrity, and authenticity. They have excellent performance and power efficiency on modern hardware. Users should use AEAD ciphers whenever possible.

The following AEAD ciphers are recommended. Compliant Shadowsocks implementations must support AEAD_CHACHA20_POLY1305. Implementations for devices with hardware AES acceleration should also implement AEAD_AES_128_GCM and AEAD_AES_256_GCM.

 

 

 

Name

Alias

Key Size

Salt Size

Nonce Size

Tag Size

AEAD_CHACHA20_POLY1305

chacha20-ietf-poly1305

32

32

12

16

AEAD_AES_256_GCM

aes-256-gcm

32

32

12

16

AEAD_AES_128_GCM

aes-128-gcm

16

16

12

16

Please refer to IANA AEAD registry for naming scheme and specification.

Key Derivation

The master key can be input directly from the user or generated from a password.

HKDF_SHA1 is a function that takes a secret key, a non-secret salt, an info string, and produces a subkey that is cryptographically strong even if the input secret key is weak.

HKDF_SHA1(key, salt, info) => subkey

The info string binds the generated subkey to a specific application context. In our case, it must be the string “ss-subkey” without quotes.

We derive a per-session subkey from a pre-shared master key using HKDF_SHA1. Salt must be unique through the entire life of the pre-shared master key.

Authenticated Encryption/Decryption

AE_encrypt is a function that takes a secret key, a non-secret nonce, a message, and produces ciphertext and an authentication tag. Nonce must be unique for a given key in each invocation.

AE_encrypt(key, nonce, message) => (ciphertext, tag)

 

AE_decrypt is a function that takes a secret key, non-secret nonce, ciphertext, an authentication tag, and produces an original message. If any of the input is tampered with, the decryption will fail.

AE_decrypt(key, nonce, ciphertext, tag) => message

TCP

An AEAD encrypted TCP stream starts with a randomly generated salt to derive the per-session subkey, followed by any number of encrypted chunks. Each chunk has the following structure:

[encrypted payload length][length tag][encrypted payload][payload tag]

 

Payload length is a 2-byte big-endian unsigned integer capped at 0x3FFF. The higher two bits are reserved and must be set to zero. Payload is therefore limited to 16*1024 – 1 bytes.

The first AEAD encrypt/decrypt operation uses a counting nonce starting from 0. After each encrypt/decrypt operation, the nonce is incremented by one as if it were an unsigned little-endian integer. Note that each TCP chunk involves two AEAD encrypt/decrypt operations: one for the payload length, and one for the payload. Therefore each chunk increases the nonce twice.

TCP

An AEAD encrypted TCP stream starts with a randomly generated salt to derive the per-session subkey, followed by any number of encrypted chunks. Each chunk has the following structure:

[encrypted payload length][length tag][encrypted payload][payload tag]

 

Payload length is a 2-byte big-endian unsigned integer capped at 0x3FFF. The higher two bits are reserved and must be set to zero. Payload is therefore limited to 16*1024 – 1 bytes.

The first AEAD encrypt/decrypt operation uses a counting nonce starting from 0. After each encrypt/decrypt operation, the nonce is incremented by one as if it were an unsigned little-endian integer. Note that each TCP chunk involves two AEAD encrypt/decrypt operations: one for the payload length, and one for the payload. Therefore each chunk increases the nonce twice.

Start your 5-day Free trial