All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.
Re-enabling AES-NI on VPSes that don't pass the feature through
Have you ever had a VPS that isn't using CPU passthrough and is not exposing AES-NI, causing really, really slow encryption? Or have you ever asked your provider to enable it but instead gotten kicked out for being "too advanced"? The solution is quite simple and just involves setting OPENSSL_ia32cap. Just run, as root:
openssl info -cpusettings | perl -pe 's/(0x[0-9a-f]{16})/sprintf("0x%016x", hex($1) | (1 << 57))/e' >> /etc/environment
Don't just copy-paste this. There's an invisible character in -pe to prevent Cloudflare from thinking this is an exploit. 🙄
So how does this work, exactly? The hypervisor, if it's not set to CPU passthrough or is not set to expose a CPU model that supports AES-NI, simply modifies the results of the CPUID instruction (it's trapped and then emulated) to not advertise the feature but, crucially, doesn't actually prevent the AES-NI instructions from working. Whenever the guest attempts to determine CPU features using CPUID, it will be told that AES-NI is not supported (even if it is!) and it will fall back to a slower, all-software implementation. But the OpenSSL library has the ability to override that detection using an environmental variable. All this one-liner does is get the exposed CPUID value, OR the value of 1 << 57 with the first logical vector, and append it to the environment file. Beware that this change is persistent and tied to the hardware you first run it on so things may break if the VPS is migrated.
Of course, the host's hardware has to actually support AES-NI. Anything in the last decade and a half is sure to, but don't expect an ancient Core2Duo to magically become an encryption beast by running this (or do anything other than crash, because this trick does disable OpenSSL's normal feature auto-detection). Also, note this only improves the performance of OpenSSL-based cryptography. Kernel cryptography will not be changed. To change that, you'd have to write a kernel module (sorry, your encrypted swap isn't getting any faster otherwise).
This trick can also be used to enable other features that might be missing, such as AVX2, RDRAND, etc. See the linked OpenSSL documentation to determine what bit to enable. Small adjustments to the Perl one-liner (beyond simply changing the bit shift amount) will be necessary if the bit is not in LV0.
There are some posts on this forum claiming that you only need to set OPENSSL_ia32cap=+0x200000200000000, but that is wrong as it will disable all other CPU features. Unfortunately, you really have to parse the entire damn string and fix it up, but Perl is really good for this kind of trick because it is designed for text processing.
If you have kernel 6.15 or newer, add this to your kernel command line and you'll also gain AES-NI acceleration in the kernel (for example, encrypted block devices or anything else that relies on the crypto API):
setcpuid=57
You can do that by adding it to GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub and then running update-grub and rebooting. This will bring "aes" back to /etc/cpuinfo, but I don't believe that will change OpenSSL's behavior on its own. For that, you still need the environmental variable trick.


Comments
I just let myself got kicked out for being too advanced instead of running the command. Worth it.
If i explicitly remove the CPU flag in qemu how can this reenable it? Is it emulated?
Because all QEMU does is change the effect of the CPUID instruction to stop advertising AES-NI support. But the AES-NI instructions can't be trapped, so they'll always work if the guest attempts to issue them and the hardware supports them.
(Edited the OP to add a more detailed explanation)
Oh okay that's actually nice. Good finding.
tempted to run this on a GCORE vps which shows QEMU virtual cpu with nothing enabled
You can test it out just by removing the
>> /etc/environmentpart. It'll output something like this:Just export that as an ennvironmental variable and try
openssl speedand see if it gets faster.Note that sometimes it'll show a QEMU virtual CPU but still support AES-NI, for example if it started with
-cpu qemu64,aes. You can check ifaesis present in/proc/cpuinfoto see if AES-NI export is advertised. If not, this trick may help!It's a bit pointless, unless you know why you need it. Modern SSH, HTTPS and VPN (Wireguard) have moved on from AES to ChaCha20, and that doesn't rely on any hardware acceleration.
AES with AES-NI is still significantly faster than software-only ChaCha20. It's quite useful for applications where you need AES, such as Tor relays or web servers that can't just tell older TLS 1.2 users to screw off.
It's not
A bit faster at the largest block size, but slower on all others, up to 10x. Checked on my home server with AMD Ryzen 5900X, bare metal (no VPS).
Sure, with Tor there is no choice what to use.
That's because you were using AES in GCM mode which requires an extra encryption step to compute the authentication tag for each block (which is really bad with small block sizes). Try it in CTR mode. It will be faster.
Another test on a different system:
(Fastest is bold)
Yeah, it appears Tor actually uses CTR, and they are replacing it with something else.
That's just the circuit layer encryption. It also has to do link-level encryption as well, which is TLS and is usually AES-GCM or ChaCha20-Poly1305, so that's a double whammy! Thankfully, TLS has a 16 KiB record size, so it doesn't use the small blocks that make GCM bad, and CGO still has the performance characteristics of CTR.
But raw AES with AES-NI will always be faster than software-only ChaCha20, as long as it's not put in a mode that's inefficient with small block sizes.