# [LINUX] Developing Cipher Algorithms (1/2)

https://www.kernel.org/doc/html/latest/crypto/devel-algos.html

Docs » Linux Kernel Crypto API » Developing Cipher Algorithms

Developing Cipher Algorithms

Registering And Unregistering Transformation

There are three distinct types of registration functions in the Crypto API. One is used to register a generic cryptographic transformation, while the other two are specific to HASH transformations and COMPRESSion. We will discuss the latter two in a separate chapter, here we will only look at the generic ones.

There are three different types of registration functions in the Crypt API. One is to register a general cryptographic transformation, and the other two are HASH trasnfomation and COMPRESSion. We'll discuss the last two on another occasion, but for now we'll only look at the very general first.

Before discussing the register functions, the data structure to be filled with each, struct crypto_alg, must be considered – see below for a description of this data structure.

Before discussing the registration function, we have to think about each data structure to fill, struct crypt_alg. See below for more information on this data structure.

The generic registration functions can be found in include/linux/crypto.h and their definition can be seen below. The former function registers a single transformation, while the latter works on an array of transformation descriptions. The latter is useful when registering transformations in bulk, for example when a driver implements multiple transformations.

Common registration functions can be found in include / linux / crypto.h and their definitions can be found below. The former function registers a single transformation, the latter registers an array of transfomation descriptors. .. The latter is useful when registering transformations in bulk. For example, if the driver implements multiple transfomations.

``````int crypto_register_alg(struct crypto_alg *alg);
int crypto_register_algs(struct crypto_alg *algs, int count);
``````

The counterparts to those functions are listed below.

The corresponding ones for these functions are:

``````void crypto_unregister_alg(struct crypto_alg *alg);
void crypto_unregister_algs(struct crypto_alg *algs, int count);
``````

The registration functions return 0 on success, or a negative errno value on failure. crypto_register_algs() succeeds only if it successfully registered all the given algorithms; if it fails partway through, then any changes are rolled back.

The registration function returns 0 on success and a negative errno value on failure. crypto_register_algs () will only succeed if the registration is successful for all given algorithms. If it fails prematurely, all changes will be rolled back.

The unregistration functions always succeed, so they don’t have a return value. Don’t try to unregister algorithms that aren’t currently registered.

The deregistration function always succeeds and has no return value. Do not attempt to unregister an algorithm that is not currently registered.

Single-Block Symmetric Ciphers [CIPHER]

Example of transformations: aes, serpent, …

This section describes the simplest of all transformation implementations, that being the CIPHER type used for symmetric ciphers. The CIPHER type is used for transformations which operate on exactly one block at a time and there are no dependencies between blocks at all.

This section describes the simplest of all transfomation implementations, the CIPHER type with symbolic ciphers. CIPHER type is used when only one block is operated at a time and there is no dependency between blocks.

Registration specifics

The registration of [CIPHER] algorithm is specific in that struct crypto_alg field .cra_type is empty. The .cra_u.cipher has to be filled in with proper callbacks to implement this transformation.

The registration of the [CIPHER] algorithm has the characteristic that the firld .cra_type of the structure cipher_alg is empty. To implement this transofrm, you must enter the appropriate callback in cra_u.cipher.

See struct cipher_alg below.

Cipher Definition With struct cipher_alg

Struct cipher_alg defines a single block cipher.

The structure cipher_alg defines a single block cipher.

Here are schematics of how these functions are called when operated from other part of the kernel. Note that the .cia_setkey() call might happen before or after any of these schematics happen, but must not happen during any of these are in-flight.

Below is a diagram showing how these functions are called when processed from other parts of the kernel. Note that cia_setkey () is called before or after these operations are performed, and never during execution.

``````
KEY ---.    PLAINTEXT ---.
v                 v
.cia_setkey() -> .cia_encrypt()
|
'-----> CIPHERTEXT

``````

Please note that a pattern where .cia_setkey() is called multiple times is also valid:

Note that a pattern in which cia_setkey () is called multiple times is also valid.

``````
KEY1 --.    PLAINTEXT1 --.         KEY2 --.    PLAINTEXT2 --.
v                 v                v                 v
.cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
|                                  |
'---> CIPHERTEXT1                  '---> CIPHERTEXT2

``````

Multi-Block Ciphers

Example of transformations: cbc(aes), chacha20, …

This section describes the multi-block cipher transformation implementations. The multi-block ciphers are used for transformations which operate on scatterlists of data supplied to the transformation functions. They output the result into a scatterlist of data as well.

This section describes the implementation of a multi-block cipher transform. The multi-block cipher is used for transforms that manipulate the scatterlist of data provided in the transfomation function. The result is also output in the data scatter list.

Registration Specifics

The registration of multi-block cipher algorithms is one of the most standard procedures throughout the crypto API.

Registering a multi-block cipher algorim is one of the most basic ways to go through the crypto API.

Note, if a cipher implementation requires a proper alignment of data, the caller should use the functions of crypto_skcipher_alignmask() to identify a memory alignment mask. The kernel crypto API is able to process requests that are unaligned. This implies, however, additional overhead as the kernel crypto API needs to perform the realignment of the data which may imply moving of data.

Note that the cipher implementation expects a proper alignment of the data. The caller must handle the memory alignment mask using the crypto_skcipher_alignmask () function. The kernel crypyo API can execute requests that do not have alignment. However, this means additional overhead, as the kernel crypto API has to perform the data readjustment, which can mean moving the data.

Cipher Definition With struct skcipher_alg

Struct skcipher_alg defines a multi-block cipher, or more generally, a length-preserving symmetric cipher algorithm.

The structure skcipher_alg defines a multi-block cipher, or more generally, a target cipher algorithm that maintains its length.

Scatterlist handling

Some drivers will want to use the Generic ScatterWalk in case the hardware needs to be fed separate chunks of the scatterlist which contains the plaintext and will contain the ciphertext. Please refer to the ScatterWalk interface offered by the Linux kernel scatter / gather list implementation.

Some drivers prefer to use Generic ScatterWalk in case you need to supply the hardware with separate chunks of scatterlist containing plaintext and ciphertext.

Recommended Posts