AES-NIとは
IntelやAMD特定のCPU(主にXeon)でサポートされているAESの暗号化/復号を高速に実行するための拡張命令セット。
ssl_engine
nginxにはssl_engine
というSSLのハードウェアアクセラレーション機能を利用するためのディレクティブがあります。ちょっと前に社内でこの機能でAES-NI使いたいよね的な話をしていていろいろ調べてたのでまとめてみました。
AES-NIが使えるかどうか調べる
AES-NIはCPUの拡張命令セットなのでまず利用しているCPUでAES-NIがサポートされている必要があります。Linuxだと/proc/cpuinfo
のflags
にaes
が含まれていなければなりません。また、Intelのサイトでもプロセッサの型番レベルで調べることができます。
$ cat /proc/cpuinfo | grep aes | wc -l
4
$
CPUの方はサポートされているのが確認できました。しかし、一方でopenssl
コマンドだとaes
の文字が見当たりません。
$ openssl engine -t -c
(rdrand) Intel RDRAND engine
[RAND]
[ available ]
(dynamic) Dynamic engine loading support
[ unavailable ]
$
ダメ元でssl_engine
にaesni
を指定してみましたが、やはりエラーになります。(no such engine:id=aesni
とか出る)
ssl_engine aesni;
わからないのでググってみる
いろいろ調べてみましたが、↓のstackoverflowやOpenSSLのMLアーカイブ(?)に回答っぽいのがありました。
stackoverflowの方の回答を抜粋すると、
In OpenSSL >= 1.0.1 AES-NI is enabled by default in the EVP interface, and there is no aesni engine. So in nginx there is no configuration option to enable AES-NI for OpenSSL versions >= 1.0.1 as it is enabled by default in OpenSSL (as long as your CPU supports it). For OpenSSL versions < 1.0.1 there is no official support for AES-NI though there is a patch available.
つまりOpenSSLのバージョンが1.0.1以上ならCPUがサポートしていればデフォルトでAES-NIが有効になるよ、ということらしいです。各所でopenssl engine -c -t
でaesniの文字が表示されてればOKという記述を見かけていたので結構ハマったのですが、これはOpenSSLのバージョンが1.0.0の頃の話のようです。
AES-NI有り/無しでベンチマーク
また、実際openssl
コマンドではAES-NIの有り/無しでベンチマークを取ってみるとかなり性能に差が出ます。
AES-NI無し
$ openssl speed aes-256-cbc
...
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-256 cbc 83516.83k 87979.03k 89286.21k 89781.93k 89983.23k
$
AES-NI有り
$ openssl speed -evp aes-256-cbc
...
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-256-cbc 410475.75k 431723.92k 434910.46k 438013.77k 437015.89k
$
という感じで性能に5倍くらいの差が出ました。
ところで、Amazon EC2 InstancesによるとEC2では現行世代のインスタンスだとすべてサポートされているようです。
まとめ
nginxのssl_engine
とAES-NIについて解説しました。今のところnginxでAES-NIを利用したい場合、CPUでサポートされていてOpenSSLのバージョンが1.0.1以上なら特に何もしなくても自動的にAES-NIが有効になるのでssl_engine
はそもそも使わなくてもいいようです。(ただ、modprobe aes-x86_64
は必要なのかな?)