Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Shells Virtual Desktop
BMail.ag - Secure Email Service
Server.net
CPLicense.net
VPS Server
Buy VPN
Vultr
VMs for AI
HostDare
HostDare
ReliableSite White-Label Dedicated Hosting for Resellers
25% Recurring Discount on NVMe VPS
InterServer VPS
BMail.ag - Secure Email Service
Best VPN
High-Performance Bare Metal Server Solutions
Karvl.com
Server Mania Cloud Hosting
DataWagon Hosting
AlphaVPS Hosting
Evoxt.com
Clouvider
VPS Hosting with NVMe
Residential IPs in the US & 4G Mobile Proxies in EU & US with Unlimited Bandwidth
ReliableSite White-Label Dedicated Hosting for Resellers
Rabisu - Hosting Solutions
Shells Virtual Desktop
New on LowEndTalk? Please Register and read our Community Rules.

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

forestforest Member
edited 8:53AM in Tutorials

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

  • sliixsliix Member

    I just let myself got kicked out for being too advanced instead of running the command. Worth it.

  • WilliamWilliam Member

    If i explicitly remove the CPU flag in qemu how can this reenable it? Is it emulated?

  • forestforest Member
    edited 8:22AM

    @William said:
    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)

  • sliixsliix Member

    @forest said:

    @William said:
    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.

  • NekoparaNekopara Member
    edited 8:30AM

    tempted to run this on a GCORE vps which shows QEMU virtual cpu with nothing enabled

  • forestforest Member
    edited 8:32AM

    @Nekopara said:
    tempted to run this on a GCORE vps which shows QEMU virtual cpu

    You can test it out just by removing the >> /etc/environment part. It'll output something like this:

    OPENSSL_ia32cap=0xfffab2234f8bffff:0x0000001cd19e4fbb:0x00000000bc000400:0x0000000000000000:0x0000000000000000
    

    Just export that as an ennvironmental variable and try openssl speed and 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 if aes is present in /proc/cpuinfo to see if AES-NI export is advertised. If not, this trick may help!

    Thanked by 1kait
  • rm_rm_ IPv6 Advocate, Veteran

    @Nekopara said: tempted to run this on a GCORE vps which shows QEMU virtual cpu with nothing enabled

    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.

  • forestforest Member
    edited 8:49AM

    @rm_ said:

    @Nekopara said: tempted to run this on a GCORE vps which shows QEMU virtual cpu with nothing enabled

    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.

  • rm_rm_ IPv6 Advocate, Veteran

    @forest said: AES with AES-NI is still significantly faster than software-only ChaCha20

    It's not

    # openssl speed -evp aes-256-gcm
    Doing AES-256-GCM for 3s on 16 size blocks: 9823762 AES-256-GCM's in 2.99s
    Doing AES-256-GCM for 3s on 64 size blocks: 9590386 AES-256-GCM's in 3.00s
    Doing AES-256-GCM for 3s on 256 size blocks: 8854658 AES-256-GCM's in 3.00s
    Doing AES-256-GCM for 3s on 1024 size blocks: 6112744 AES-256-GCM's in 3.00s
    Doing AES-256-GCM for 3s on 8192 size blocks: 1692182 AES-256-GCM's in 3.00s
    Doing AES-256-GCM for 3s on 16384 size blocks: 946772 AES-256-GCM's in 3.00s
    version: 3.0.20
    built on: Sat Jun  6 19:56:20 2026 UTC
    options: bn(64,64)
    compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -fzero-call-used-regs=used-gpr -DOPENSSL_TLS_SECURITY_LEVEL=2 -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/reproducible-path/openssl-3.0.20=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
    CPUINFO: OPENSSL_ia32cap=0x7ed8320b078bffff:0x40069c219c95a9
    The 'numbers' are in 1000s of bytes per second processed.
    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
    AES-256-GCM      52568.63k   204594.90k   755597.48k  2086483.29k  4620784.98k  5170637.48k
    
    # openssl speed -evp chacha20
    Doing ChaCha20 for 3s on 16 size blocks: 93741413 ChaCha20's in 3.00s
    Doing ChaCha20 for 3s on 64 size blocks: 39662584 ChaCha20's in 3.00s
    Doing ChaCha20 for 3s on 256 size blocks: 26229574 ChaCha20's in 3.00s
    Doing ChaCha20 for 3s on 1024 size blocks: 13588427 ChaCha20's in 3.00s
    Doing ChaCha20 for 3s on 8192 size blocks: 1730923 ChaCha20's in 3.00s
    Doing ChaCha20 for 3s on 16384 size blocks: 866005 ChaCha20's in 2.99s
    version: 3.0.20
    built on: Sat Jun  6 19:56:20 2026 UTC
    options: bn(64,64)
    compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -fzero-call-used-regs=used-gpr -DOPENSSL_TLS_SECURITY_LEVEL=2 -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/reproducible-path/openssl-3.0.20=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
    CPUINFO: OPENSSL_ia32cap=0x7ed8320b078bffff:0x40069c219c95a9
    The 'numbers' are in 1000s of bytes per second processed.
    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
    ChaCha20        499954.20k   846135.13k  2238256.98k  4638183.08k  4726573.74k  4745359.84k

    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).

    @forest said: It's quite useful for applications where you need AES, such as Tor relays.

    Sure, with Tor there is no choice what to use.

  • forestforest Member
    edited 9:21AM

    @rm_ said: It's not

    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.

    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes   16384 bytes
    ChaCha20        227516.99k   383953.85k  1497240.82k  3130150.57k  3436038.83k  3357950.28k
    AES-256-GCM      55436.01k   217551.04k   812752.30k  1971706.54k  4776331.95k  5288525.82k
    AES-256-CTR     469902.65k  1255179.20k  2833732.32k  3949237.17k  4639984.42k  4650707.63k
    

    Another test on a different system:

    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes   16384 bytes
    ChaCha20        344771.51k   551873.95k  1403153.10k  3007458.55k  3092409.00k  3139125.08k
    AES-256-GCM      56719.83k   215587.48k   720461.40k  1784048.42k  3116755.35k  3428984.27k
    AES-256-CTR     569387.82k  1886783.42k  4343309.06k  5839836.50k  6580028.10k  6597288.84k
    

    (Fastest is bold)

    Thanked by 2Murv Nekopara
  • rm_rm_ IPv6 Advocate, Veteran

    @forest said: Try it with CTR mode. It will be faster.

    Yeah, it appears Tor actually uses CTR, and they are replacing it with something else.

  • forestforest Member

    @rm_ said:

    @forest said: Try it with CTR mode. It will be faster.

    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. ;)

Sign In or Register to comment.