3rd Generation Intel® Xeon® Scalable Processors における暗号処理の高速化について
3rd Generation Xeon において追加された Crypto Acceleration についてのまとめです。
おかしな部分等あれば指摘いただけると幸いです。
概要
3rd Generation Intel® Xeon® Scalable processors (と一部の第 10 世代 Core シリーズ)においては AVX512 系の命令がいくつか追加されており、それらの命令を利用することで暗号処理の高速化を実現することができます。
これらの高速化に関連する拡張命令は次の 4 つです。
- AVX512F
- AVX512_IFMA
- 積和演算(fuse multiply add)のための命令
- VAES
- VPCLMULQDQ
- (英語版 wikipediaより抜粋・翻訳) これらは AVX-512 の機能それ自体ではありません。AVX-512 とともに、GFNI、PCLMULQDQ、AES 命令の EVEX エンコード版を実現します。
また、これらの拡張命令を CPU が利用できるかは次のコマンドで確かめることができます
$ cpuid -1 | egrep 'VAES|VPCLM|GFNI|AVX512F|AVX512IFMA'
AVX512F: AVX-512 foundation instructions = true
AVX512IFMA: fused multiply add = true
VAES instructions = true
VPCLMULQDQ instruction = true
後述するIntel® Quick Assist Technology (Intel® QAT) Engineの利用のためにはこれらの拡張命令をすべて利用できる必要があります
高速化の恩恵を受けるための各種ライブラリについて
Intel® Integrated Performance Primitives Cryptography (ipp-crypto)
x86-64 における各種 SIMD 命令(Streaming SIMD Extesions, AVX, AVX2, AVX512 等)を利用した暗号処理が提供されています
この中にCrypto Multi-buffer Libraryというのが入っており、これが AVX512 系の命令を使って暗号処理、特に RSA, ECDSA, SM3, x25519 を扱うことができるライブラリです。
Intel(R) Multi-Buffer Crypto for IPsec Library (intel-ipsec-mb)
AES 系の暗号はこちらで実装されています。各種の暗号と拡張命令を利用した実装状況に関してはREADME の Overviewに詳しいです。
Intel® QuickAssist Technology(QAT) OpenSSL* Engine
これは、先述の 2 つのライブラリを利用して OpenSSL の処理を高速化するためのライブラリです。
このライブラリには特殊なハードウェアを利用したqat_hw
の実装と、SIMD 系命令を利用したqat_sw
を利用した実装の 2 種類が存在し、3rd Generation 以降の Xeon で利用できるのはqat_sw
の方の実装になります。
OpenSSL にはEngineという特殊なハードウェア実装を用いて処理を高速化するための仕組みをもとから備えており、それを経由して AVX512 系の命令を利用した高速化を行うことができます。
利用のためには制約もあり、OpenSSL は静的リンクされたものではなく共有ライブラリとしてビルドされたものからしか利用できません。
また、GitHub の README には OpenSSL 1.1 系での利用方法しか書いていませんが、OpenSSL 3 や BoringSSL からでも利用できます。
OpenSSL v3.1 以降
changelog によると、OpenSSL の 3.1 系では AVX512 系命令を利用した AES-GCM が有効化されています。
(https://github.com/openssl/openssl/blob/master/CHANGES.md#:~:text=AES-GCM enabled with AVX512 vAES and vPCLMULQDQ)
ベンチマーク
QAT Engine を利用した OpenSSL3.0 系と OpenSSL3.1-beta1 において検証を行いました。
検証環境の構築
GCP の n2-standard-8 インスタンスを用いて検証を行いました。
N2 インスタンスでは Ice Lake のプロセッサ(=3rd Generation Xeon)を選択できます。
QAT Engine のビルド
基本的には
こちらの手順にしたがってビルドができます。ただし、OpenSSL は 3.0.2(Ubuntu 22.04 のデフォルト)、ipp-crypto は2021.7、intel-ipsec-mb はv1.3を利用しました。
また、QAT Engine に関してもv0.6.19を利用しました。
OpenSSL 3.1 のビルド
./Configure no-shared
を指定してビルドしたものを利用しました。
結果
OpenSSL 3.0.2 + QAT Engine での結果
$ openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
$ openssl engine -v qatengine
(qatengine) Reference implementation of QAT crypto engine(qat_sw) v0.6.19
ENABLE_EXTERNAL_POLLING, POLL, ENABLE_HEURISTIC_POLLING,
GET_NUM_REQUESTS_IN_FLIGHT, INIT_ENGINE, SW_ALGO_BITMAP
809B1728167F0000:error:1280006A:DSO support routines:dlfcn_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_dlfcn.c:188:symname(EVP_PKEY_base_id): /usr/lib/x86_64-linux-gnu/engines-3/qatengine.so: undefined symbol: EVP_PKEY_base_id
809B1728167F0000:error:1280006A:DSO support routines:DSO_bind_func:could not bind to the requested symbol name:../crypto/dso/dso_lib.c:176:
なんかエラー出てるけどよくわからないので誰か教えてください
aes-128-gcm
QAT Engine なし
$ openssl speed -evp aes-128-gcm
Doing AES-128-GCM for 3s on 16 size blocks: 127992858 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 64 size blocks: 76284376 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 256 size blocks: 42488086 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 1024 size blocks: 15397757 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 8192 size blocks: 2273200 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 16384 size blocks: 1150996 AES-128-GCM's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
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-GCM 682628.58k 1627400.02k 3625650.01k 5255767.72k 6207351.47k 6285972.82k
QAT Engine あり
$ openssl speed -engine qatengine -evp aes-128-gcm
Engine "qatengine" set.
Doing AES-128-GCM for 3s on 16 size blocks: 109974541 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 64 size blocks: 89364103 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 256 size blocks: 50045002 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 1024 size blocks: 29516005 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 8192 size blocks: 4564498 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 16384 size blocks: 2353982 AES-128-GCM's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
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-GCM 586530.89k 1906434.20k 4270506.84k 10074796.37k 12464122.54k 12855880.36k
1024 bytes 以降は大体 2 倍くらい速い
aes-128-ctr
QAT Engine なし
$ openssl speed -evp aes-128-ctr
Doing AES-128-CTR for 3s on 16 size blocks: 177189451 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 64 size blocks: 129222686 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 256 size blocks: 71686196 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 1024 size blocks: 25626352 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 8192 size blocks: 3662314 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 16384 size blocks: 1840201 AES-128-CTR's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
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-CTR 945010.41k 2756750.63k 6117222.06k 8747128.15k 10000558.76k 10049951.06k
QAT Engine あり
$ openssl speed -engine qatengine -evp aes-128-ctr
Engine "qatengine" set.
Doing AES-128-CTR for 3s on 16 size blocks: 177708180 AES-128-CTR's in 2.99s
Doing AES-128-CTR for 3s on 64 size blocks: 129253145 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 256 size blocks: 71697346 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 1024 size blocks: 25668842 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 8192 size blocks: 3655854 AES-128-CTR's in 3.00s
Doing AES-128-CTR for 3s on 16384 size blocks: 1843037 AES-128-CTR's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
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-CTR 950946.78k 2757400.43k 6118173.53k 8761631.40k 9982918.66k 10065439.40k
変化なし
chacha20-poly1305
QAT Engine なし
$ openssl speed -evp chacha20-poly1305
Doing ChaCha20-Poly1305 for 3s on 16 size blocks: 51876085 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 64 size blocks: 25916354 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 256 size blocks: 21052322 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 1024 size blocks: 9419079 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 8192 size blocks: 1337422 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 16384 size blocks: 672829 ChaCha20-Poly1305's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
ChaCha20-Poly1305 276672.45k 552882.22k 1796464.81k 3215045.63k 3652053.67k 3674543.45k
QAT Engine あり
$ openssl speed -engine qatengine -evp chacha20-poly1305
Engine "qatengine" set.
Doing ChaCha20-Poly1305 for 3s on 16 size blocks: 51898009 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 64 size blocks: 26196760 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 256 size blocks: 21134291 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 1024 size blocks: 9479344 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 8192 size blocks: 1336801 ChaCha20-Poly1305's in 3.00s
Doing ChaCha20-Poly1305 for 3s on 16384 size blocks: 672172 ChaCha20-Poly1305's in 3.00s
version: 3.0.2
built on: Mon Feb 6 17:57:17 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-hnAO60/openssl-3.0.2=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
ChaCha20-Poly1305 276789.38k 558864.21k 1803459.50k 3235616.09k 3650357.93k 3670955.35k
変化なし
OpenSSL 3.1.0-beta1 での結果
$ ./openssl speed -evp aes-128-gcm
Doing AES-128-GCM for 3s on 16 size blocks: 136722134 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 64 size blocks: 127713350 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 256 size blocks: 62024856 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 1024 size blocks: 20155531 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 8192 size blocks: 4373650 AES-128-GCM's in 3.00s
Doing AES-128-GCM for 3s on 16384 size blocks: 2313676 AES-128-GCM's in 3.00s
version: 3.1.0-beta1
built on: Fri Mar 10 10:35:57 2023 UTC
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG
CPUINFO: OPENSSL_ia32cap=0xfefa32035f8bffff:0x405f46f1bf2ffb
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-GCM 729184.71k 2724551.47k 5292787.71k 6879754.58k 11942980.27k 12635755.86k
大体 QAT Engine ありと同じくらいの結果が出ています。
その他のベンチマーク
intel 公式から nginx などのソフトウェアを利用したベンチマークなども公開されています。
まとめ
3rd Generation Xeon での暗号処理では OpenSSL3.0.2 において QAT Engine を利用するか、もしくは 3.1 系へと移行することで AES-128-GCM で最大 2 倍程度の高速化を実現できることがわかりました。
もしこれらのプロセッサを利用することができ、暗号処理がボトルネックになっている場合は今後 OpenSSL3.1 への移行などを検討する価値はありそうです。
Discussion