Use ChaCha encryption algorithms instead of AES for HTTPS

The ARX family of encryption algorithms perform much better on platforms that don’t provide hardware acceleration due to their simplicity. I run seafile on docker on a server with an old AMD processor, for most stuff it’s fine but it really struggles with HTTPS, mainly because of the lack of AES-NI. Is there a way I can configure nginx inside the docker image so that it always uses ChaCha20 as the encryption algorithm? Also since I’m using the included Let’s Encrypt scripts to renew the cert it might be required to change some stuff there too.

1 Like

It seems this also applies to the Raspberry Pi 4: https://www.raspberrypi.org/forums/viewtopic.php?t=259588

I ran some benchmarks on my rpi4, I’m not sure how representative this is, but for bigger blocks chacha20 seems to be almost an order of magnitude faster.

ubuntu@hostia-pi:~$ openssl speed -evp chacha20-poly1305 aes-128-cbc
Doing aes-128 cbc for 3s on 16 size blocks: 13685530 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 64 size blocks: 3638358 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 256 size blocks: 921172 aes-128 cbc's in 2.99s
Doing aes-128 cbc for 3s on 1024 size blocks: 232101 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 8192 size blocks: 28986 aes-128 cbc's in 3.00s
Doing aes-128 cbc for 3s on 16384 size blocks: 14524 aes-128 cbc's in 2.99s
Doing chacha20-poly1305 for 3s on 16 size blocks: 12831157 chacha20-poly1305's in 3.00s
Doing chacha20-poly1305 for 3s on 64 size blocks: 5478244 chacha20-poly1305's in 3.00s
Doing chacha20-poly1305 for 3s on 256 size blocks: 2543592 chacha20-poly1305's in 3.00s
Doing chacha20-poly1305 for 3s on 1024 size blocks: 747603 chacha20-poly1305's in 3.00s
Doing chacha20-poly1305 for 3s on 8192 size blocks: 95788 chacha20-poly1305's in 2.99s
Doing chacha20-poly1305 for 3s on 16384 size blocks: 48155 chacha20-poly1305's in 3.00s
OpenSSL 1.1.1f  31 Mar 2020
built on: Mon Mar 22 11:33:17 2021 UTC
options:bn(64,64) rc4(char) des(int) aes(partial) blowfish(ptr)
compiler: gcc -fPIC -pthread -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-aTNdtV/openssl-1.1.1f=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DVPAES_ASM -DECP_NISTZ256_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128 cbc          72989.49k   77618.30k    78869.58k    79223.81k    79151.10k    79585.69k
chacha20-poly1305    68432.84k   116869.21k   217053.18k   255181.82k   262439.90k   262990.51k

Simple. Edit your autogenerated nginx.conf ssl_ciphers to include and exclude those you prefer.

That actually doesn’t work, all the mobile and desktop apps reject tls handshakes with the following ciphers:

  • ECDHE-ECDSA-CHACHA20-POLY1305
  • ECDHE-RSA-CHACHA20-POLY1305
  • DHE-RSA-CHACHA20-POLY1305

However Chrome and Firefox on desktop and mobile are able to establish the HTTPS link without any issues. I’m guessing this is due to these apps not bundling those algorithms with the final binaries. It’s kind of ironic considering how these do not require any type of hardware acceleration to not be 10 times slower or leaking secret bits.

1 Like

Confirmed, breaks MacOS sync client. Works fine from web browser.

Strange, I would have expected some fellow Pi users to take interest in this. Allowing only AES for https really kills performance in my case. To avoid this issue I just switched back to http over ZeroTier, zt uses Salsa20 for encryption which is way faster.

1 Like

I’ve submitted an issue to the seadroid repo addressing this

Also found these “whitelisted” ciphers in the desktop app

Here’s the issue on github

With this and the previous issue resolved using ChaCha20 as the https cipher should be viable.