This is based on RidgeRun's autotools version of the original af_alg project.
- linux kernel >= 2.6.38 with crypto/user modules enabled
- openssl source (development headers)
./configure make
make install
$ openssl speed -evp aes-128-cbc -engine af_alg -elapsed
The above command can be run with and without the -elapsed
parameter; the
latter timing is sometimes on the order of the measurement resolution, so it
may jump around depending on instantaneous machine load (using the -elapsed
parameter seems more stable).
You can also replace the -evp
argument with sha1, sha256, etc.
Note
Check your distribution's path to the openssl engines; it may be the
same place as the internal openssl engines, or a separate directory.
The default location is plugindir=$(libdir)/ssl/engines
but will
most likely change to openssl-1.0.2
instead of just ssl
. If
needed you should change it in Makefile.in and re-run configure, make,
etc.
Both Gentoo and Debian/Ubuntu packages and the dist tarball source are available, in addition to this repository (note that you need to run the autogen.sh script before you can run configure if you clone the git repo). You only need to do one of the following.
To build the Gentoo package, emerge it:
$ emerge af_alg
To install the Ubuntu package on x86/amd64, you'll need to add the PPA first, then update, and then install it. For non-x86 architectures, see the deb build HOWTO. For the binary packages, browse to the launchpad ppa page and follow the instructions, or just run the following command to add the ppa:
$ sudo add-apt-repository ppa:nerdboy/ppa-crypto $ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7774ED19 $ sudo apt-get update $ sudo apt-get install af-alg
Get the source tarball and follow the steps above:
$ wget http://dev.gentoo.org/~nerdboy/files/af_alg-0.0.1.tar.gz
The algorithms run by af_alg can be configured in the openssl.cnf file by setting the CIPHERS and DIGEST values. Not setting them will speedup nothing. The idea is to run algorithms via af_alg which can be accelerated via hardware. Since there is no documented "query" interface, you'll need to know your kernel config (mainly the cryptographic and library sections) since the key hardware drivers are specific to each architecture/machine variant.
In your kernel source tree, do:
$ sudo make menuconfig
and check/enable the crypto modules and user space modules for your architecture:
-*- Cryptographic API ---> Library routines ---> --- Cryptographic API *** Crypto core or helper *** <M> RSA algorithm -*- Cryptographic algorithm manager <M> Userspace cryptographic algorithm configuration
The basic required crypto/hash modules are:
{*} Authenc support {*} CCM support {M} CBC support -*- CTR support {M} CTS support {M} ECB support {M} LRW support {M} PCBC support {M} XTS support *** Hash modes *** {M} CMAC support -*- HMAC support -*- CRC32c CRC algorithm -*- CRCT10DIF algorithm -*- GHASH digest algorithm {M} Poly1305 authenticator algorithm -*- MD5 digest algorithm -*- SHA1 digest algorithm -*- SHA224 and SHA256 digest algorithm {M} SHA384 and SHA512 digest algorithms -*- AES cipher algorithms {*} ARC4 cipher algorithm {M} CAST5 (CAST-128) cipher algorithm {*} DES and Triple DES EDE cipher algorithms *** Compression *** {M} Deflate compression algorithm <*> LZO compression algorithm *** Random Number Generation *** -*- NIST SP800-90A DRBG ---> -*- Jitterentropy Non-Deterministic Random Number Generator [*] Hardware crypto devices ---> -*- Asymmetric (public-key cryptographic) key type --->
The library section is much shorter; if not selected, select the BCJ filter decoder that matches your hardware:
{M} CRC32c (Castagnoli, et al) Cyclic Redundancy-Check <*> XZ decompression support [*] x86 BCJ filter decoder [ ] PowerPC BCJ filter decoder [ ] IA-64 BCJ filter decoder [ ] ARM BCJ filter decoder [ ] ARM-Thumb BCJ filter decoder [ ] SPARC BCJ filter decoder
In /etc/ssl/openssl.cnf
openssl_conf = openssl_def [openssl_def] engines = openssl_engines [openssl_engines] af_alg = af_alg_engine [af_alg_engine] default_algorithms = ALL CIPHERS=aes-128-cbc aes-192-cbc aes-256-cbc des-cbc des-ede3-cbc DIGESTS=md4 md5 sha1 sha224 sha256 sha512
This will enforce loading the af_alg OpenSSL dynamic engine by default, so it can be used by OpenSSH. Starting with OpenSSH 5.4p1 OpenSSH honors the openssl config and will use your default engines specified.
Make sure you have at least:
algif_hash 12943 0 algif_skcipher 17369 0 af_alg 14686 2 algif_hash,algif_skcipher
in your lsmod output.
If you can't load the modules, check the kernel config options again. Grep is your friend here:
$ grep CRYPTO_USER_API /usr/src/linux/.config CONFIG_CRYPTO_USER_API=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m
and make sure the above modules are in your kernel config.
If you have hardware crypto support for large block sizes, AF_ALG is supposed to increase performance; for small block sizes, the overhead introduced by AF_ALG may slow things down. In case you are looking for better performance, you might need a dedicated hardware crypto device. Cryptodev is another option, however, cryptodev is also somewhat slower for smaller block sizes, but should provide a significant boost for 8192 size blocks.
engine "af_alg" type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes aes-128-cbc 7952.93k 33862.40k 141754.51k 640204.80k 2575564.80k engine "cryptodev" aes-128-cbc 5654.96k 17000.96k 141747.20k 384430.08k 2564915.20k engine "builtin" (Cavium Octeon modules) aes-128-cbc 9700.32k 86694.40k 91764.36k 646519.47k 2578841.60k
Note
The above numbers were generated on an EdgeRouter Lite mips64 system using a mainline kernel.
Linux edgerouter 4.5.1 #7 SMP PREEMPT Thu Apr 21 12:37:02 PDT 2016 mips64 Cavium Octeon+ V0.1 UBNT_E100 (CN5020p1.1-500-SCP) GNU/Linux
OpenSSL ships evp_test, which can be used to verify things work. A patch on OpenSSL is required to force evp_test using the config.
diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c index ad36b84..d40c461 100644 --- a/crypto/evp/evp_test.c +++ b/crypto/evp/evp_test.c @@ -532,8 +532,8 @@ int main(int argc,char **argv) /* Load all compiled-in ENGINEs */ ENGINE_load_builtin_engines(); #endif -#if 0 - OPENSSL_config(); +#if 1 + OPENSSL_config(NULL); #endif #ifndef OPENSSL_NO_ENGINE /* Register all available ENGINE implementations of ciphers and digests.
Create a config /tmp/af_alg.cnf with mentioned modifications to force using the engine:
export OPENSSL_CONF=/tmp/af_alg.cnf openssl/test$ ./evp_test evptests.txt
It will fail if the computed results do not match the expected results. Compiling the engine with:
make CFLAGS=-DDEBUG clean all
may help as well.
cconf can be used to modify the crypto priorities on kernels >= 3.2
- https://events.linuxfoundation.org/sites/events/files/slides/lcj-2014-crypto-user.pdf
- http://article.gmane.org/gmane.linux.kernel.cryptoapi/5292
- http://article.gmane.org/gmane.linux.kernel.cryptoapi/5296
- https://bugzilla.mindrot.org/show_bug.cgi?id=1707
- http://thread.gmane.org/gmane.linux.kernel.cryptoapi/6045
- http://sourceforge.net/projects/crconf/
- Markus Koetter
- Carsten Behling <carsten.behling@ridgerun.com>
- Stephen Arnold <stephen.arnold42@gmail.com>