FreeBSD + AESNI + OpenSSL + OpenVPN

FreeBSD
Тема апгрейда домашнего файл-сервера назрела давно, все ждал когда появятся в нашем маленьком городке процессоры на архитектуре Sandy Bridge. И вот, дождался!

После не долгих раздумий выбор пал на Intel Core i5-2400. Купил материнскую плату на новом сокете (1155), новую оперативку и вставил туда новый процессор.

Система загрузилась без каких либо проблем. Процессор опознался так:
CPU: Intel® Core(TM) i5-2400 CPU @ 3.10GHz (3092.99-MHz K8-class CPU)
Origin = "GenuineIntel"  Id = 0x206a7  Family = 6  Model = 2a  Stepping = 7
Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PB
Features2=0x17bae3ff<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,<b24>,AESNI,XSA
AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
AMD Features2=0x1<LAHF>


И сразу захотелось попробовать AESNI. Вкратце, это набор инструкций процессора, облегчающий работу алгоритма симметричного шифрования AES.
Попробую предоставить результаты своих экспериментов.

Первым делом обновил ядро до последней версии:

mira# uname a
FreeBSD mira.s25.tmb.local 8.2-PRERELEASE FreeBSD 8.2-PRERELEASE  #24 r217405M: Fri Jan 14 17:47:28 MSK 2011 root@mira.s25.tmb.local:/usr/obj/usr/src/sys/mira amd64


След. этап — это подготовка к работе OpenSSL. OpenSSL может использовать криптоустройства, для этого понадобится внести в ядро некоторые изменения:
device crypto
device cryptodev


Пересобираю ядро, ребут, устройство появилось:
mira# ls -l /dev/crypto
crw-rw-rw-  1 root  wheel    0,  50 14 янв 17:50 /dev/crypto


Проверяю, видит ли его OpenSSL:
mira# openssl engine -c -t
(cryptodev) BSD cryptodev engine
 [RSA, DSA, DH]
     [ available ]
(dynamic) Dynamic engine loading support
     [ unavailable ]

Через /dev/crypto доступны RSA, DSA и DH. Начинаю тестировать AES-128-CBC при программном шифровании:
mira# openssl speed -evp aes-128-cbc -elapsed -engine cryptodev


Произвел 3 попытки, результат выглядит так:

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128-cbc     149333.49k   161474.81k   166845.20k   169239.74k   169526.84k
aes-128-cbc     149383.88k   161576.08k   166807.70k   169247.59k   169332.38k
aes-128-cbc     149306.18k   161567.85k   166893.00k   169253.79k   169442.78k

Прокомментировать можно так — 16 байтовые блоки на программном шифровании ведут себя хуже всего.

Теперь собираю драйвер AESNI. Для этого нужно произвести следующие действия:
mira# cd /usr/src/sys/modules/aesni/
mira# make && make install && make cleandir

Драйвер собран, подгружаю:
mira# kldload aesni
mira# tail /var/log/messages
...
Jan 14 20:12:42 mira kernel: aesni0: <AES-CBC,AES-XTS> on motherboard

Как видно — предоставляются следующие алгоритмы, AES-CBC и AES-XTS.

Проверяю, что видит из них OpenSSL:
mira# openssl engine -c -t
(cryptodev) BSD cryptodev engine
 [RSA, DSA, DH, AES-128-CBC]
     [ available ]
(dynamic) Dynamic engine loading support
     [ unavailable ]

Как видно — к первым трем еще добавился AES-128-CBC.
Приступаю к тестированию, результаты такие:

aes-128-cbc       2765.78k    10888.17k    41067.49k   133714.48k   365408.09k
aes-128-cbc       2748.99k    10924.15k    41003.44k   133949.67k   365854.75k
aes-128-cbc       2766.53k    10974.47k    41186.70k   134004.88k   365284.89k


Цифры очень странные… Пробую провести тестирование в 4 потока.

4 потока, программное шифрование:

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128 cbc     546199.48k   628730.19k   613435.01k   631914.96k   634100.26k
aes-128 cbc     604568.61k   627207.28k   615642.83k   632113.57k   635981.79k
aes-128 cbc     601480.22k   626961.80k   611012.14k   629367.81k   635527.17k
aes-128 cbc     602734.16k   627857.32k   613340.57k   628279.12k   635088.71k
aes-128 cbc     600113.42k   624894.35k   615254.44k   629211.91k   639963.36k


4 потока, драйвер AESNI загружен:

evp               5309.13k    21143.50k    84258.72k   329655.51k   986809.86k
evp               5284.27k    21177.89k    83595.91k   326792.76k   955406.32k
evp               5304.14k    21172.89k    83623.38k   327369.47k   972340.27k


И снова довольно странные результаты…

Чтож, приступаю к тестированию целевой задачи, а именно OpenVPN.

Результаты, AESNI не используется:

mira# time openvpn --test-crypto --secret /tmp/huy --verb 0 --tun-mtu 20000 --cipher aes-128-cbc
17.876u 0.007s 0:17.89 99.8%    638+894k 0+0io 0pf+0w
17.874u 0.007s 0:17.89 99.8%    638+894k 0+0io 0pf+0w
17.882u 0.000s 0:17.89 99.9%    638+894k 0+0io 0pf+0w


Подгружаю AESNI и повторяю тестирование:

mira# kldload aesni
mira# time openvpn --test-crypto --secret /tmp/huy --verb 0 --tun-mtu 20000 --cipher aes-128-cbc
15.414u 1.014s 0:16.44 99.8%    639+894k 0+0io 0pf+0w
15.291u 1.112s 0:16.41 99.9%    638+894k 0+0io 0pf+0w
15.566u 0.835s 0:16.41 99.8%    637+892k 0+0io 0pf+0w


Здесь прекрасно видно, что использование AESNI уже дает прирост в скорости, 16.41 против 18.89 секунд, почти на 1.5 секунды быстрее. Причем прекрасно заметно, что работа в userland уменьшилась чуть больше 2 секунд, и переложилась одной секундой на system.
Надо отметить, что в данном тестировании основная нагрузка это не шифрование, поэтому выигрыш порядка 20% смотрится очень солидно.

В результате этих эксперементов для себя почерпнул следующее:
— Использование AESNI дает приророст к быстродействию;
— OpenSSL до версии 0.9.8q дает очень странные цифры при использовании AESNI;
— OpenSSL официально будет поддерживать AESNI с версии 1.0.1;
— OpenVPN в связке OpenSSL + cryptodev дает прирост быстродействия порядка 20%.

3 комментария

avatar
Не, я так считаю — апгрейд «домашнего файл-сервера» нужно делать только на Corei7
avatar
i7 — необоснованный перебор :)
avatar
Thank you for this article. It was very helpful in understanding what was going on with the aesni driver and the openssl benchmarks. I got about 2x speed increase for 1024 and 8192 byte blocks on our Xeon E5620s though.

Instead of compiling the devices into the kernel I added them to loader.conf by adding the two following lines:
aesni_load=«YES»
cryptodev_load=«YES»

But when I try to use ie. cURL to do HTTPS calls, they will fail if cryptodev and aesni is enabled, are you having the same issues?

Please see my problem report:
www.freebsd.org/cgi/query-pr.cgi?pr=155160
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.