| Kernel Crypto API Architecture | |
| ============================== | |
| Cipher algorithm types | |
| ---------------------- | |
| The kernel crypto API provides different API calls for the following | |
| cipher types: | |
| - Symmetric ciphers | |
| - AEAD ciphers | |
| - Message digest, including keyed message digest | |
| - Random number generation | |
| - User space interface | |
| Ciphers And Templates | |
| --------------------- | |
| The kernel crypto API provides implementations of single block ciphers | |
| and message digests. In addition, the kernel crypto API provides | |
| numerous "templates" that can be used in conjunction with the single | |
| block ciphers and message digests. Templates include all types of block | |
| chaining mode, the HMAC mechanism, etc. | |
| Single block ciphers and message digests can either be directly used by | |
| a caller or invoked together with a template to form multi-block ciphers | |
| or keyed message digests. | |
| A single block cipher may even be called with multiple templates. | |
| However, templates cannot be used without a single cipher. | |
| See /proc/crypto and search for "name". For example: | |
| - aes | |
| - ecb(aes) | |
| - cmac(aes) | |
| - ccm(aes) | |
| - rfc4106(gcm(aes)) | |
| - sha1 | |
| - hmac(sha1) | |
| - authenc(hmac(sha1),cbc(aes)) | |
| In these examples, "aes" and "sha1" are the ciphers and all others are | |
| the templates. | |
| Synchronous And Asynchronous Operation | |
| -------------------------------------- | |
| The kernel crypto API provides synchronous and asynchronous API | |
| operations. | |
| When using the synchronous API operation, the caller invokes a cipher | |
| operation which is performed synchronously by the kernel crypto API. | |
| That means, the caller waits until the cipher operation completes. | |
| Therefore, the kernel crypto API calls work like regular function calls. | |
| For synchronous operation, the set of API calls is small and | |
| conceptually similar to any other crypto library. | |
| Asynchronous operation is provided by the kernel crypto API which | |
| implies that the invocation of a cipher operation will complete almost | |
| instantly. That invocation triggers the cipher operation but it does not | |
| signal its completion. Before invoking a cipher operation, the caller | |
| must provide a callback function the kernel crypto API can invoke to | |
| signal the completion of the cipher operation. Furthermore, the caller | |
| must ensure it can handle such asynchronous events by applying | |
| appropriate locking around its data. The kernel crypto API does not | |
| perform any special serialization operation to protect the caller's data | |
| integrity. | |
| Crypto API Cipher References And Priority | |
| ----------------------------------------- | |
| A cipher is referenced by the caller with a string. That string has the | |
| following semantics: | |
| :: | |
| template(single block cipher) | |
| where "template" and "single block cipher" is the aforementioned | |
| template and single block cipher, respectively. If applicable, | |
| additional templates may enclose other templates, such as | |
| :: | |
| template1(template2(single block cipher))) | |
| The kernel crypto API may provide multiple implementations of a template | |
| or a single block cipher. For example, AES on newer Intel hardware has | |
| the following implementations: AES-NI, assembler implementation, or | |
| straight C. Now, when using the string "aes" with the kernel crypto API, | |
| which cipher implementation is used? The answer to that question is the | |
| priority number assigned to each cipher implementation by the kernel | |
| crypto API. When a caller uses the string to refer to a cipher during | |
| initialization of a cipher handle, the kernel crypto API looks up all | |
| implementations providing an implementation with that name and selects | |
| the implementation with the highest priority. | |
| Now, a caller may have the need to refer to a specific cipher | |
| implementation and thus does not want to rely on the priority-based | |
| selection. To accommodate this scenario, the kernel crypto API allows | |
| the cipher implementation to register a unique name in addition to | |
| common names. When using that unique name, a caller is therefore always | |
| sure to refer to the intended cipher implementation. | |
| The list of available ciphers is given in /proc/crypto. However, that | |
| list does not specify all possible permutations of templates and | |
| ciphers. Each block listed in /proc/crypto may contain the following | |
| information -- if one of the components listed as follows are not | |
| applicable to a cipher, it is not displayed: | |
| - name: the generic name of the cipher that is subject to the | |
| priority-based selection -- this name can be used by the cipher | |
| allocation API calls (all names listed above are examples for such | |
| generic names) | |
| - driver: the unique name of the cipher -- this name can be used by the | |
| cipher allocation API calls | |
| - module: the kernel module providing the cipher implementation (or | |
| "kernel" for statically linked ciphers) | |
| - priority: the priority value of the cipher implementation | |
| - refcnt: the reference count of the respective cipher (i.e. the number | |
| of current consumers of this cipher) | |
| - selftest: specification whether the self test for the cipher passed | |
| - type: | |
| - skcipher for symmetric key ciphers | |
| - cipher for single block ciphers that may be used with an | |
| additional template | |
| - shash for synchronous message digest | |
| - ahash for asynchronous message digest | |
| - aead for AEAD cipher type | |
| - compression for compression type transformations | |
| - rng for random number generator | |
| - givcipher for cipher with associated IV generator (see the geniv | |
| entry below for the specification of the IV generator type used by | |
| the cipher implementation) | |
| - kpp for a Key-agreement Protocol Primitive (KPP) cipher such as | |
| an ECDH or DH implementation | |
| - blocksize: blocksize of cipher in bytes | |
| - keysize: key size in bytes | |
| - ivsize: IV size in bytes | |
| - seedsize: required size of seed data for random number generator | |
| - digestsize: output size of the message digest | |
| - geniv: IV generation type: | |
| - eseqiv for encrypted sequence number based IV generation | |
| - seqiv for sequence number based IV generation | |
| - chainiv for chain iv generation | |
| - <builtin> is a marker that the cipher implements IV generation and | |
| handling as it is specific to the given cipher | |
| Key Sizes | |
| --------- | |
| When allocating a cipher handle, the caller only specifies the cipher | |
| type. Symmetric ciphers, however, typically support multiple key sizes | |
| (e.g. AES-128 vs. AES-192 vs. AES-256). These key sizes are determined | |
| with the length of the provided key. Thus, the kernel crypto API does | |
| not provide a separate way to select the particular symmetric cipher key | |
| size. | |
| Cipher Allocation Type And Masks | |
| -------------------------------- | |
| The different cipher handle allocation functions allow the specification | |
| of a type and mask flag. Both parameters have the following meaning (and | |
| are therefore not covered in the subsequent sections). | |
| The type flag specifies the type of the cipher algorithm. The caller | |
| usually provides a 0 when the caller wants the default handling. | |
| Otherwise, the caller may provide the following selections which match | |
| the aforementioned cipher types: | |
| - CRYPTO_ALG_TYPE_CIPHER Single block cipher | |
| - CRYPTO_ALG_TYPE_COMPRESS Compression | |
| - CRYPTO_ALG_TYPE_AEAD Authenticated Encryption with Associated Data | |
| (MAC) | |
| - CRYPTO_ALG_TYPE_BLKCIPHER Synchronous multi-block cipher | |
| - CRYPTO_ALG_TYPE_ABLKCIPHER Asynchronous multi-block cipher | |
| - CRYPTO_ALG_TYPE_GIVCIPHER Asynchronous multi-block cipher packed | |
| together with an IV generator (see geniv field in the /proc/crypto | |
| listing for the known IV generators) | |
| - CRYPTO_ALG_TYPE_KPP Key-agreement Protocol Primitive (KPP) such as | |
| an ECDH or DH implementation | |
| - CRYPTO_ALG_TYPE_DIGEST Raw message digest | |
| - CRYPTO_ALG_TYPE_HASH Alias for CRYPTO_ALG_TYPE_DIGEST | |
| - CRYPTO_ALG_TYPE_SHASH Synchronous multi-block hash | |
| - CRYPTO_ALG_TYPE_AHASH Asynchronous multi-block hash | |
| - CRYPTO_ALG_TYPE_RNG Random Number Generation | |
| - CRYPTO_ALG_TYPE_AKCIPHER Asymmetric cipher | |
| - CRYPTO_ALG_TYPE_PCOMPRESS Enhanced version of | |
| CRYPTO_ALG_TYPE_COMPRESS allowing for segmented compression / | |
| decompression instead of performing the operation on one segment | |
| only. CRYPTO_ALG_TYPE_PCOMPRESS is intended to replace | |
| CRYPTO_ALG_TYPE_COMPRESS once existing consumers are converted. | |
| The mask flag restricts the type of cipher. The only allowed flag is | |
| CRYPTO_ALG_ASYNC to restrict the cipher lookup function to | |
| asynchronous ciphers. Usually, a caller provides a 0 for the mask flag. | |
| When the caller provides a mask and type specification, the caller | |
| limits the search the kernel crypto API can perform for a suitable | |
| cipher implementation for the given cipher name. That means, even when a | |
| caller uses a cipher name that exists during its initialization call, | |
| the kernel crypto API may not select it due to the used type and mask | |
| field. | |
| Internal Structure of Kernel Crypto API | |
| --------------------------------------- | |
| The kernel crypto API has an internal structure where a cipher | |
| implementation may use many layers and indirections. This section shall | |
| help to clarify how the kernel crypto API uses various components to | |
| implement the complete cipher. | |
| The following subsections explain the internal structure based on | |
| existing cipher implementations. The first section addresses the most | |
| complex scenario where all other scenarios form a logical subset. | |
| Generic AEAD Cipher Structure | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| The following ASCII art decomposes the kernel crypto API layers when | |
| using the AEAD cipher with the automated IV generation. The shown | |
| example is used by the IPSEC layer. | |
| For other use cases of AEAD ciphers, the ASCII art applies as well, but | |
| the caller may not use the AEAD cipher with a separate IV generator. In | |
| this case, the caller must generate the IV. | |
| The depicted example decomposes the AEAD cipher of GCM(AES) based on the | |
| generic C implementations (gcm.c, aes-generic.c, ctr.c, ghash-generic.c, | |
| seqiv.c). The generic implementation serves as an example showing the | |
| complete logic of the kernel crypto API. | |
| It is possible that some streamlined cipher implementations (like | |
| AES-NI) provide implementations merging aspects which in the view of the | |
| kernel crypto API cannot be decomposed into layers any more. In case of | |
| the AES-NI implementation, the CTR mode, the GHASH implementation and | |
| the AES cipher are all merged into one cipher implementation registered | |
| with the kernel crypto API. In this case, the concept described by the | |
| following ASCII art applies too. However, the decomposition of GCM into | |
| the individual sub-components by the kernel crypto API is not done any | |
| more. | |
| Each block in the following ASCII art is an independent cipher instance | |
| obtained from the kernel crypto API. Each block is accessed by the | |
| caller or by other blocks using the API functions defined by the kernel | |
| crypto API for the cipher implementation type. | |
| The blocks below indicate the cipher type as well as the specific logic | |
| implemented in the cipher. | |
| The ASCII art picture also indicates the call structure, i.e. who calls | |
| which component. The arrows point to the invoked block where the caller | |
| uses the API applicable to the cipher type specified for the block. | |
| :: | |
| kernel crypto API | IPSEC Layer | |
| | | |
| +-----------+ | | |
| | | (1) | |
| | aead | <----------------------------------- esp_output | |
| | (seqiv) | ---+ | |
| +-----------+ | | |
| | (2) | |
| +-----------+ | | |
| | | <--+ (2) | |
| | aead | <----------------------------------- esp_input | |
| | (gcm) | ------------+ | |
| +-----------+ | | |
| | (3) | (5) | |
| v v | |
| +-----------+ +-----------+ | |
| | | | | | |
| | skcipher | | ahash | | |
| | (ctr) | ---+ | (ghash) | | |
| +-----------+ | +-----------+ | |
| | | |
| +-----------+ | (4) | |
| | | <--+ | |
| | cipher | | |
| | (aes) | | |
| +-----------+ | |
| The following call sequence is applicable when the IPSEC layer triggers | |
| an encryption operation with the esp_output function. During | |
| configuration, the administrator set up the use of rfc4106(gcm(aes)) as | |
| the cipher for ESP. The following call sequence is now depicted in the | |
| ASCII art above: | |
| 1. esp_output() invokes crypto_aead_encrypt() to trigger an | |
| encryption operation of the AEAD cipher with IV generator. | |
| In case of GCM, the SEQIV implementation is registered as GIVCIPHER | |
| in crypto_rfc4106_alloc(). | |
| The SEQIV performs its operation to generate an IV where the core | |
| function is seqiv_geniv(). | |
| 2. Now, SEQIV uses the AEAD API function calls to invoke the associated | |
| AEAD cipher. In our case, during the instantiation of SEQIV, the | |
| cipher handle for GCM is provided to SEQIV. This means that SEQIV | |
| invokes AEAD cipher operations with the GCM cipher handle. | |
| During instantiation of the GCM handle, the CTR(AES) and GHASH | |
| ciphers are instantiated. The cipher handles for CTR(AES) and GHASH | |
| are retained for later use. | |
| The GCM implementation is responsible to invoke the CTR mode AES and | |
| the GHASH cipher in the right manner to implement the GCM | |
| specification. | |
| 3. The GCM AEAD cipher type implementation now invokes the SKCIPHER API | |
| with the instantiated CTR(AES) cipher handle. | |
| During instantiation of the CTR(AES) cipher, the CIPHER type | |
| implementation of AES is instantiated. The cipher handle for AES is | |
| retained. | |
| That means that the SKCIPHER implementation of CTR(AES) only | |
| implements the CTR block chaining mode. After performing the block | |
| chaining operation, the CIPHER implementation of AES is invoked. | |
| 4. The SKCIPHER of CTR(AES) now invokes the CIPHER API with the AES | |
| cipher handle to encrypt one block. | |
| 5. The GCM AEAD implementation also invokes the GHASH cipher | |
| implementation via the AHASH API. | |
| When the IPSEC layer triggers the esp_input() function, the same call | |
| sequence is followed with the only difference that the operation starts | |
| with step (2). | |
| Generic Block Cipher Structure | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Generic block ciphers follow the same concept as depicted with the ASCII | |
| art picture above. | |
| For example, CBC(AES) is implemented with cbc.c, and aes-generic.c. The | |
| ASCII art picture above applies as well with the difference that only | |
| step (4) is used and the SKCIPHER block chaining mode is CBC. | |
| Generic Keyed Message Digest Structure | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Keyed message digest implementations again follow the same concept as | |
| depicted in the ASCII art picture above. | |
| For example, HMAC(SHA256) is implemented with hmac.c and | |
| sha256_generic.c. The following ASCII art illustrates the | |
| implementation: | |
| :: | |
| kernel crypto API | Caller | |
| | | |
| +-----------+ (1) | | |
| | | <------------------ some_function | |
| | ahash | | |
| | (hmac) | ---+ | |
| +-----------+ | | |
| | (2) | |
| +-----------+ | | |
| | | <--+ | |
| | shash | | |
| | (sha256) | | |
| +-----------+ | |
| The following call sequence is applicable when a caller triggers an HMAC | |
| operation: | |
| 1. The AHASH API functions are invoked by the caller. The HMAC | |
| implementation performs its operation as needed. | |
| During initialization of the HMAC cipher, the SHASH cipher type of | |
| SHA256 is instantiated. The cipher handle for the SHA256 instance is | |
| retained. | |
| At one time, the HMAC implementation requires a SHA256 operation | |
| where the SHA256 cipher handle is used. | |
| 2. The HMAC instance now invokes the SHASH API with the SHA256 cipher | |
| handle to calculate the message digest. |