gsliepen / tinc

a VPN daemon
http://tinc-vpn.org/
Other
1.97k stars 285 forks source link

Feature Request: AES support for 1.1 #267

Open splitice opened 3 years ago

splitice commented 3 years ago

I'd like to see a command line flag or configuration option for AES (via AES-NI) support for tinc1.1

Clients should negotiate based on the availability for AES-NI on both systems.

gsliepen commented 3 years ago

Yes, this is something I would like in 1.1, mainly to have an alternative cipher available in case Chacha20-Poly1305 would be broken.

splitice commented 3 years ago

From #110

But according to @gsliepen, this is not so easy / there is trade-off involved, because the OpenSSL interface that Tinc used in the past for AES(-NI) is not quite stable. Maybe libsodium could be used instead? No software fallback seems to be provided though.

@gsliepen AES-NI is available for any EVP call now days. No need to change crypto library.

Verified with openssl speed which doesnt look to be doing anything special.

Default:

openssl speed -elapsed -evp aes-128-ecb
You have chosen to measure elapsed time instead of user CPU time.
Doing aes-128-ecb for 3s on 16 size blocks: 79616759 aes-128-ecb's in 3.00s
[...]

Disabling AES-NI:

OPENSSL_ia32cap="~0x200000200000000" openssl speed -elapsed -evp aes-128-ecb
You have chosen to measure elapsed time instead of user CPU time.
Doing aes-128-ecb for 3s on 16 size blocks: 34159253 aes-128-ecb's in 3.00s
splitice commented 3 years ago

@gsliepen gcrypt also has support for AES-NI as of 1.5.0 (https://www.phoronix.com/scan.php?page=news_item&px=OTYxMw)

It looks to be automatically detected and used if available on the processor.

splitice commented 3 years ago

I investigated AES-NI detection and detirmined it to be a bit of a pain. Easier on newer GCCs but older GCCs are finiky requiring autoconf or ifdefs by GCC version.

Given that the same effect can be acheived using a Cipher Priorities and blacklisting I'm leaning that way.

e.g preferred AES

Cipher=aes128,chacha

or disabled AES

Cipher=chacha
splitice commented 3 years ago

I've currently acheived my first communicating builds with AES in place of chacha. I still need to integrate sequence numbers and digest checks (since the polly tag isnt in use). I also need to get no legacy builds working again since they remove some of the required objects currently.

I wonder if poly1305_auth would be a good idea. I've never heard of AES+poly1305 but I don't see why not.

splitice commented 3 years ago

In regards to cipher negotiation @gsliepen will need to do a protocol extension for integration.

I don't want to be making breaking protocol changes or introducing a protocol fork.

splitice commented 3 years ago

Looking at the available APIs for AES it doesnt look I can feed the IV with seqnums easily for each encrypt. The AES-GCM standard for inspiration it does a fixed IV with seqnum as first bytes. I figure we should do the same.

The only question is should the IV just be an extension of the prf space so that the single call generates key+iv or is there something else (something better)?

gsliepen commented 3 years ago

To encrypt individual packets, the typical way to do this would be to use an IV of 96 bits that consists of:

The last 32 bits are the counter added by the AES-GCM algorithm itself.

Anyway, AES-GCM is probably the way to go, if poly1305 is broken you don't want both algorithms depending on that. It's also quite efficient on Intel processors using the PCLMULQDQ instruction.

gsliepen commented 3 years ago

AES-256-GCM support has been added in the feature/alt-ciphersuite branch. Still missing are configuration options to select which algorithms to allow and prefer.

splitice commented 3 years ago

@gsliepen I left a few comments from a read through of the commit.

I should be able to fire up a test network with it over the weekend and give it a run.

MonwF commented 2 years ago

AES-256-GCM support has been added in the feature/alt-ciphersuite branch. Still missing are configuration options to select which algorithms to allow and prefer.

I've set up a test network with newly built binary, but how to enable AES-256-GCM or verify it works

tinc -n foo dump nodes outputs

abc id 7c65964be990 at 1.1.1.1 port 20422 cipher 0 digest 0 maclength 0 compression 0 options 700000c status 08da nexthop abc via abc distance 1 pmtu 1431 (min 1431 max 1431) rx 2 196 tx 4 376 rtt 50.634
xyz id b917a71e72a4 at MYSELF port 20422 cipher 0 digest 0 maclength 0 compression 0 options 700000c status 0058 nexthop xyz via xyz distance 0 pmtu 1518 (min 0 max 1518) rx 69 9234 tx 62 47091
gsliepen commented 2 years ago

I've set up a test network with newly built binary, but how to enable AES-256-GCM or verify it works

Good point, at the moment this is not logged anywhere. In the branch, AES-256-GCM is enabled automatically if both sides are compiled with OpenSSL or LibreSSL support. If you want to verify it yourself, you could add some debugging printfs to cipher_init() in src/sptps.c.