|
@@ -0,0 +1,435 @@
|
|
|
+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)
|
|
|
+
|
|
|
+- 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_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.
|