Newer Intel and AMD x86 and x64 processors provide support for Advanced Encryption Standard (AES) cipher operations within their instruction set; these are known as AES-NI instructions. The purpose of this project is to use AES-NI instructions when possible in order to speed up AES encryption and decryption.
Externally visible behavior
The build system will automatically detect whether AES-NI support can be compiled, on platforms which can support it. The --disable-aesni configure flag will prevent AES-NI support from being built; the --enable-aesni flag will trigger an error if AES-NI support cannot be built.
When AES-NI support is enabled at build time, both the regular C implementation of AES and the assembly implementation using AES-NI instructions will be built. At runtime, the AES-NI version will be used if a runtime check for AES-NI support succeeds, and the C version will be used if it does not.
If the OpenSSL or NSS crypto back end is selected at build time, there will be no changes (using AES-NI instructions or not will be the responsibility of the underlying crypto library).
Intel provides a sample implementation of assembly routines using AES-NI instructions, called the Intel AESNI Sample Library, which is released under a 3-clause BSD license. The assembly functions in this library provide key expansion functions for 128-bit, 192-bit, and 256-bit encryption and decryption keys, and in-place ECB, CBC, and CTR encryption and decryption functions for each of those key sizes.
The krb5 AES encryption provider accepts a chain of iov structures to be encrypted or decrypted in-place. Plaintext or ciphertext blocks may cross the boundaries of IOVs, forcing copies for individual blocks at the IOV boundaries. But for the case where an IOV contains many contiguous blocks, the highest efficiency will come from invoking the assembly CBC encryption or decryption function across those blocks. To that end, two preparatory steps are required:
1. Alter the crypto IOV helpers to support accessing a sequence of contiguous blocks within an IOV. The IOV crypto helpers are currently more complicated than necessary due to past attempts at supporting CCM-mode enctypes; this project will rewrite them to be simpler from the caller's perspective.
2. Rewrite the builtin AES enc provider to use in-place CBC encryption and decryption as its fundamental primitives. At the same time, factor out all access to the cached key schedule so that helper functions can be used as an integration point for using AES-NI primitives.
The assembly sources from the Intel sample library will be imported and modified to (a) remove the functions we don't need (functions using 192-bit encryption keys and ECB-mode and CTR-mode enryption and decryption functions), and (b) use %defines to rename the functions we do need to use a k5_ prefix.
In configure.in, if AES-NI support is not explicitly disabled with --disable-aesni, we will enable build-time support for AES-NI if we find that all of the following are true:
- We are building for an i686 or x86_64 host.
- The yasm command is present.
- The cpuid.h header is present.
An assembly file and yasm flags will be selected based on the host platform, and the AESNI symbol will be defined.
If the AESNI symbol is defined, the AES enc provider will:
- When the key schedule cache is instantiated, use __get_cpuid() (from cpuid.h) to detect whether AES-NI instructions are supported and set a flag in the cache structure.
- If the AES-NI support flag is set in the key schedule cache structure, use the Intel assembly functions for key expansion, encryption, and decryption.
If the AESNI symbol is not defined, the helper functions to invoke the Intel assembly functions will be #defined away.
Informal testing suggests that using AES-NI improves encryption and decryption speed substantially (perhaps 140%) for large payloads, but only by a small amount (perhaps 10%) for small payloads where overhead dominates.
The k5crypto library is already covered by extensive automated tests.
The --disable-aesni flag will be documented in doing_build.rst.
- The AES-based encryption types will use AES-NI instructions when possible for improved performance.