1 Developing Cipher Algorithms
2 ============================
4 Registering And Unregistering Transformation
5 --------------------------------------------
7 There are three distinct types of registration functions in the Crypto
8 API. One is used to register a generic cryptographic transformation,
9 while the other two are specific to HASH transformations and
10 COMPRESSion. We will discuss the latter two in a separate chapter, here
11 we will only look at the generic ones.
13 Before discussing the register functions, the data structure to be
14 filled with each, struct crypto_alg, must be considered -- see below
15 for a description of this data structure.
17 The generic registration functions can be found in
18 include/linux/crypto.h and their definition can be seen below. The
19 former function registers a single transformation, while the latter
20 works on an array of transformation descriptions. The latter is useful
21 when registering transformations in bulk, for example when a driver
22 implements multiple transformations.
26 int crypto_register_alg(struct crypto_alg *alg);
27 int crypto_register_algs(struct crypto_alg *algs, int count);
30 The counterparts to those functions are listed below.
34 void crypto_unregister_alg(struct crypto_alg *alg);
35 void crypto_unregister_algs(struct crypto_alg *algs, int count);
38 The registration functions return 0 on success, or a negative errno
39 value on failure. crypto_register_algs() succeeds only if it
40 successfully registered all the given algorithms; if it fails partway
41 through, then any changes are rolled back.
43 The unregistration functions always succeed, so they don't have a
44 return value. Don't try to unregister algorithms that aren't
47 Single-Block Symmetric Ciphers [CIPHER]
48 ---------------------------------------
50 Example of transformations: aes, serpent, ...
52 This section describes the simplest of all transformation
53 implementations, that being the CIPHER type used for symmetric ciphers.
54 The CIPHER type is used for transformations which operate on exactly one
55 block at a time and there are no dependencies between blocks at all.
57 Registration specifics
58 ~~~~~~~~~~~~~~~~~~~~~~
60 The registration of [CIPHER] algorithm is specific in that struct
61 crypto_alg field .cra_type is empty. The .cra_u.cipher has to be
62 filled in with proper callbacks to implement this transformation.
64 See struct cipher_alg below.
66 Cipher Definition With struct cipher_alg
67 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69 Struct cipher_alg defines a single block cipher.
71 Here are schematics of how these functions are called when operated from
72 other part of the kernel. Note that the .cia_setkey() call might happen
73 before or after any of these schematics happen, but must not happen
74 during any of these are in-flight.
78 KEY ---. PLAINTEXT ---.
80 .cia_setkey() -> .cia_encrypt()
85 Please note that a pattern where .cia_setkey() is called multiple times
91 KEY1 --. PLAINTEXT1 --. KEY2 --. PLAINTEXT2 --.
93 .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
95 '---> CIPHERTEXT1 '---> CIPHERTEXT2
101 Example of transformations: cbc(aes), chacha20, ...
103 This section describes the multi-block cipher transformation
104 implementations. The multi-block ciphers are used for transformations
105 which operate on scatterlists of data supplied to the transformation
106 functions. They output the result into a scatterlist of data as well.
108 Registration Specifics
109 ~~~~~~~~~~~~~~~~~~~~~~
111 The registration of multi-block cipher algorithms is one of the most
112 standard procedures throughout the crypto API.
114 Note, if a cipher implementation requires a proper alignment of data,
115 the caller should use the functions of crypto_skcipher_alignmask() to
116 identify a memory alignment mask. The kernel crypto API is able to
117 process requests that are unaligned. This implies, however, additional
118 overhead as the kernel crypto API needs to perform the realignment of
119 the data which may imply moving of data.
121 Cipher Definition With struct skcipher_alg
122 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124 Struct skcipher_alg defines a multi-block cipher, or more generally, a
125 length-preserving symmetric cipher algorithm.
130 Some drivers will want to use the Generic ScatterWalk in case the
131 hardware needs to be fed separate chunks of the scatterlist which
132 contains the plaintext and will contain the ciphertext. Please refer
133 to the ScatterWalk interface offered by the Linux kernel scatter /
134 gather list implementation.
139 Example of transformations: crc32, md5, sha1, sha256,...
141 Registering And Unregistering The Transformation
142 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144 There are multiple ways to register a HASH transformation, depending on
145 whether the transformation is synchronous [SHASH] or asynchronous
146 [AHASH] and the amount of HASH transformations we are registering. You
147 can find the prototypes defined in include/crypto/internal/hash.h:
151 int crypto_register_ahash(struct ahash_alg *alg);
153 int crypto_register_shash(struct shash_alg *alg);
154 int crypto_register_shashes(struct shash_alg *algs, int count);
157 The respective counterparts for unregistering the HASH transformation
162 void crypto_unregister_ahash(struct ahash_alg *alg);
164 void crypto_unregister_shash(struct shash_alg *alg);
165 void crypto_unregister_shashes(struct shash_alg *algs, int count);
168 Cipher Definition With struct shash_alg and ahash_alg
169 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171 Here are schematics of how these functions are called when operated from
172 other part of the kernel. Note that the .setkey() call might happen
173 before or after any of these schematics happen, but must not happen
174 during any of these are in-flight. Please note that calling .init()
175 followed immediately by .finish() is also a perfectly valid
182 .init() -> .update() -> .final() ! .update() might not be called
183 ^ | | at all in this scenario.
186 II) DATA -----------.-----------.
188 .init() -> .update() -> .finup() ! .update() may not be called
189 ^ | | at all in this scenario.
192 III) DATA -----------.
194 .digest() ! The entire process is handled
195 | by the .digest() call.
196 '---------------> HASH
199 Here is a schematic of how the .export()/.import() functions are called
200 when used from another part of the kernel.
205 v v ! .update() may not be called
206 .setkey() -> .init() -> .update() -> .export() at all in this scenario.
208 '-----' '--> PARTIAL_HASH
210 ----------- other transformations happen here -----------
212 PARTIAL_HASH--. DATA1--.
214 .import -> .update() -> .final() ! .update() may not be called
215 ^ | | at all in this scenario.
218 PARTIAL_HASH--. DATA2-.
222 '---------------> HASH2
224 Note that it is perfectly legal to "abandon" a request object:
225 - call .init() and then (as many times) .update()
226 - _not_ call any of .final(), .finup() or .export() at any point in future
228 In other words implementations should mind the resource allocation and clean-up.
229 No resources related to request objects should remain allocated after a call
230 to .init() or .update(), since there might be no chance to free them.
233 Specifics Of Asynchronous HASH Transformation
234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
236 Some of the drivers will want to use the Generic ScatterWalk in case the
237 implementation needs to be fed separate chunks of the scatterlist which
238 contains the input data. The buffer containing the resulting hash will
239 always be properly aligned to .cra_alignmask so there is no need to