Linux Audio

Check our new training course

Linux kernel drivers training

May 6-19, 2025
Register
Loading...
v6.13.7
  1Developing Cipher Algorithms
  2============================
  3
  4Registering And Unregistering Transformation
  5--------------------------------------------
  6
  7There are three distinct types of registration functions in the Crypto
  8API. One is used to register a generic cryptographic transformation,
  9while the other two are specific to HASH transformations and
 10COMPRESSion. We will discuss the latter two in a separate chapter, here
 11we will only look at the generic ones.
 12
 13Before discussing the register functions, the data structure to be
 14filled with each, struct crypto_alg, must be considered -- see below
 15for a description of this data structure.
 16
 17The generic registration functions can be found in
 18include/linux/crypto.h and their definition can be seen below. The
 19former function registers a single transformation, while the latter
 20works on an array of transformation descriptions. The latter is useful
 21when registering transformations in bulk, for example when a driver
 22implements multiple transformations.
 23
 24::
 25
 26       int crypto_register_alg(struct crypto_alg *alg);
 27       int crypto_register_algs(struct crypto_alg *algs, int count);
 28
 29
 30The counterparts to those functions are listed below.
 31
 32::
 33
 34       void crypto_unregister_alg(struct crypto_alg *alg);
 35       void crypto_unregister_algs(struct crypto_alg *algs, int count);
 36
 37
 38The registration functions return 0 on success, or a negative errno
 39value on failure.  crypto_register_algs() succeeds only if it
 40successfully registered all the given algorithms; if it fails partway
 41through, then any changes are rolled back.
 42
 43The unregistration functions always succeed, so they don't have a
 44return value.  Don't try to unregister algorithms that aren't
 45currently registered.
 
 
 
 
 
 
 
 
 
 
 46
 47Single-Block Symmetric Ciphers [CIPHER]
 48---------------------------------------
 49
 50Example of transformations: aes, serpent, ...
 51
 52This section describes the simplest of all transformation
 53implementations, that being the CIPHER type used for symmetric ciphers.
 54The CIPHER type is used for transformations which operate on exactly one
 55block at a time and there are no dependencies between blocks at all.
 56
 57Registration specifics
 58~~~~~~~~~~~~~~~~~~~~~~
 59
 60The registration of [CIPHER] algorithm is specific in that struct
 61crypto_alg field .cra_type is empty. The .cra_u.cipher has to be
 62filled in with proper callbacks to implement this transformation.
 63
 64See struct cipher_alg below.
 65
 66Cipher Definition With struct cipher_alg
 67~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 68
 69Struct cipher_alg defines a single block cipher.
 70
 71Here are schematics of how these functions are called when operated from
 72other part of the kernel. Note that the .cia_setkey() call might happen
 73before or after any of these schematics happen, but must not happen
 74during any of these are in-flight.
 75
 76::
 77
 78             KEY ---.    PLAINTEXT ---.
 79                    v                 v
 80              .cia_setkey() -> .cia_encrypt()
 81                                      |
 82                                      '-----> CIPHERTEXT
 83
 84
 85Please note that a pattern where .cia_setkey() is called multiple times
 86is also valid:
 87
 88::
 89
 90
 91      KEY1 --.    PLAINTEXT1 --.         KEY2 --.    PLAINTEXT2 --.
 92             v                 v                v                 v
 93       .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
 94                               |                                  |
 95                               '---> CIPHERTEXT1                  '---> CIPHERTEXT2
 96
 97
 98Multi-Block Ciphers
 99-------------------
100
101Example of transformations: cbc(aes), chacha20, ...
102
103This section describes the multi-block cipher transformation
104implementations. The multi-block ciphers are used for transformations
105which operate on scatterlists of data supplied to the transformation
106functions. They output the result into a scatterlist of data as well.
107
108Registration Specifics
109~~~~~~~~~~~~~~~~~~~~~~
110
111The registration of multi-block cipher algorithms is one of the most
112standard procedures throughout the crypto API.
113
114Note, if a cipher implementation requires a proper alignment of data,
115the caller should use the functions of crypto_skcipher_alignmask() to
116identify a memory alignment mask. The kernel crypto API is able to
117process requests that are unaligned. This implies, however, additional
118overhead as the kernel crypto API needs to perform the realignment of
119the data which may imply moving of data.
120
121Cipher Definition With struct skcipher_alg
122~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
124Struct skcipher_alg defines a multi-block cipher, or more generally, a
125length-preserving symmetric cipher algorithm.
126
127Scatterlist handling
128~~~~~~~~~~~~~~~~~~~~
129
130Some drivers will want to use the Generic ScatterWalk in case the
131hardware needs to be fed separate chunks of the scatterlist which
132contains the plaintext and will contain the ciphertext. Please refer
133to the ScatterWalk interface offered by the Linux kernel scatter /
134gather list implementation.
 
 
 
 
 
135
136Hashing [HASH]
137--------------
138
139Example of transformations: crc32, md5, sha1, sha256,...
140
141Registering And Unregistering The Transformation
142~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
143
144There are multiple ways to register a HASH transformation, depending on
145whether the transformation is synchronous [SHASH] or asynchronous
146[AHASH] and the amount of HASH transformations we are registering. You
147can find the prototypes defined in include/crypto/internal/hash.h:
148
149::
150
151       int crypto_register_ahash(struct ahash_alg *alg);
152
153       int crypto_register_shash(struct shash_alg *alg);
154       int crypto_register_shashes(struct shash_alg *algs, int count);
155
156
157The respective counterparts for unregistering the HASH transformation
158are as follows:
159
160::
161
162       void crypto_unregister_ahash(struct ahash_alg *alg);
163
164       void crypto_unregister_shash(struct shash_alg *alg);
165       void crypto_unregister_shashes(struct shash_alg *algs, int count);
166
167
168Cipher Definition With struct shash_alg and ahash_alg
169~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170
171Here are schematics of how these functions are called when operated from
172other part of the kernel. Note that the .setkey() call might happen
173before or after any of these schematics happen, but must not happen
174during any of these are in-flight. Please note that calling .init()
175followed immediately by .final() is also a perfectly valid
176transformation.
177
178::
179
180       I)   DATA -----------.
181                            v
182             .init() -> .update() -> .final()      ! .update() might not be called
183                         ^    |         |            at all in this scenario.
184                         '----'         '---> HASH
185
186       II)  DATA -----------.-----------.
187                            v           v
188             .init() -> .update() -> .finup()      ! .update() may not be called
189                         ^    |         |            at all in this scenario.
190                         '----'         '---> HASH
191
192       III) DATA -----------.
193                            v
194                        .digest()                  ! The entire process is handled
195                            |                        by the .digest() call.
196                            '---------------> HASH
197
198
199Here is a schematic of how the .export()/.import() functions are called
200when used from another part of the kernel.
201
202::
203
204       KEY--.                 DATA--.
205            v                       v                  ! .update() may not be called
206        .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
207                                 ^     |         |
208                                 '-----'         '--> PARTIAL_HASH
209
210       ----------- other transformations happen here -----------
211
212       PARTIAL_HASH--.   DATA1--.
213                     v          v
214                 .import -> .update() -> .final()     ! .update() may not be called
215                             ^    |         |           at all in this scenario.
216                             '----'         '--> HASH1
217
218       PARTIAL_HASH--.   DATA2-.
219                     v         v
220                 .import -> .finup()
221                               |
222                               '---------------> HASH2
223
224Note 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
227
228In other words implementations should mind the resource allocation and clean-up.
229No resources related to request objects should remain allocated after a call
230to .init() or .update(), since there might be no chance to free them.
231
232
233Specifics Of Asynchronous HASH Transformation
234~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
235
236Some of the drivers will want to use the Generic ScatterWalk in case the
237implementation needs to be fed separate chunks of the scatterlist which
238contains the input data.
 
 
v4.17
  1Developing Cipher Algorithms
  2============================
  3
  4Registering And Unregistering Transformation
  5--------------------------------------------
  6
  7There are three distinct types of registration functions in the Crypto
  8API. One is used to register a generic cryptographic transformation,
  9while the other two are specific to HASH transformations and
 10COMPRESSion. We will discuss the latter two in a separate chapter, here
 11we will only look at the generic ones.
 12
 13Before discussing the register functions, the data structure to be
 14filled with each, struct crypto_alg, must be considered -- see below
 15for a description of this data structure.
 16
 17The generic registration functions can be found in
 18include/linux/crypto.h and their definition can be seen below. The
 19former function registers a single transformation, while the latter
 20works on an array of transformation descriptions. The latter is useful
 21when registering transformations in bulk, for example when a driver
 22implements multiple transformations.
 23
 24::
 25
 26       int crypto_register_alg(struct crypto_alg *alg);
 27       int crypto_register_algs(struct crypto_alg *algs, int count);
 28
 29
 30The counterparts to those functions are listed below.
 31
 32::
 33
 34       int crypto_unregister_alg(struct crypto_alg *alg);
 35       int crypto_unregister_algs(struct crypto_alg *algs, int count);
 36
 37
 38Notice that both registration and unregistration functions do return a
 39value, so make sure to handle errors. A return code of zero implies
 40success. Any return code < 0 implies an error.
 41
 42The bulk registration/unregistration functions register/unregister each
 43transformation in the given array of length count. They handle errors as
 44follows:
 45
 46-  crypto_register_algs() succeeds if and only if it successfully
 47   registers all the given transformations. If an error occurs partway
 48   through, then it rolls back successful registrations before returning
 49   the error code. Note that if a driver needs to handle registration
 50   errors for individual transformations, then it will need to use the
 51   non-bulk function crypto_register_alg() instead.
 52
 53-  crypto_unregister_algs() tries to unregister all the given
 54   transformations, continuing on error. It logs errors and always
 55   returns zero.
 56
 57Single-Block Symmetric Ciphers [CIPHER]
 58---------------------------------------
 59
 60Example of transformations: aes, arc4, ...
 61
 62This section describes the simplest of all transformation
 63implementations, that being the CIPHER type used for symmetric ciphers.
 64The CIPHER type is used for transformations which operate on exactly one
 65block at a time and there are no dependencies between blocks at all.
 66
 67Registration specifics
 68~~~~~~~~~~~~~~~~~~~~~~
 69
 70The registration of [CIPHER] algorithm is specific in that struct
 71crypto_alg field .cra_type is empty. The .cra_u.cipher has to be
 72filled in with proper callbacks to implement this transformation.
 73
 74See struct cipher_alg below.
 75
 76Cipher Definition With struct cipher_alg
 77~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 78
 79Struct cipher_alg defines a single block cipher.
 80
 81Here are schematics of how these functions are called when operated from
 82other part of the kernel. Note that the .cia_setkey() call might happen
 83before or after any of these schematics happen, but must not happen
 84during any of these are in-flight.
 85
 86::
 87
 88             KEY ---.    PLAINTEXT ---.
 89                    v                 v
 90              .cia_setkey() -> .cia_encrypt()
 91                                      |
 92                                      '-----> CIPHERTEXT
 93
 94
 95Please note that a pattern where .cia_setkey() is called multiple times
 96is also valid:
 97
 98::
 99
100
101      KEY1 --.    PLAINTEXT1 --.         KEY2 --.    PLAINTEXT2 --.
102             v                 v                v                 v
103       .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
104                               |                                  |
105                               '---> CIPHERTEXT1                  '---> CIPHERTEXT2
106
107
108Multi-Block Ciphers
109-------------------
110
111Example of transformations: cbc(aes), ecb(arc4), ...
112
113This section describes the multi-block cipher transformation
114implementations. The multi-block ciphers are used for transformations
115which operate on scatterlists of data supplied to the transformation
116functions. They output the result into a scatterlist of data as well.
117
118Registration Specifics
119~~~~~~~~~~~~~~~~~~~~~~
120
121The registration of multi-block cipher algorithms is one of the most
122standard procedures throughout the crypto API.
123
124Note, if a cipher implementation requires a proper alignment of data,
125the caller should use the functions of crypto_skcipher_alignmask() to
126identify a memory alignment mask. The kernel crypto API is able to
127process requests that are unaligned. This implies, however, additional
128overhead as the kernel crypto API needs to perform the realignment of
129the data which may imply moving of data.
130
131Cipher Definition With struct blkcipher_alg and ablkcipher_alg
132~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133
134Struct blkcipher_alg defines a synchronous block cipher whereas struct
135ablkcipher_alg defines an asynchronous block cipher.
136
137Please refer to the single block cipher description for schematics of
138the block cipher usage.
139
140Specifics Of Asynchronous Multi-Block Cipher
141~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142
143There are a couple of specifics to the asynchronous interface.
144
145First of all, some of the drivers will want to use the Generic
146ScatterWalk in case the hardware needs to be fed separate chunks of the
147scatterlist which contains the plaintext and will contain the
148ciphertext. Please refer to the ScatterWalk interface offered by the
149Linux kernel scatter / gather list implementation.
150
151Hashing [HASH]
152--------------
153
154Example of transformations: crc32, md5, sha1, sha256,...
155
156Registering And Unregistering The Transformation
157~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158
159There are multiple ways to register a HASH transformation, depending on
160whether the transformation is synchronous [SHASH] or asynchronous
161[AHASH] and the amount of HASH transformations we are registering. You
162can find the prototypes defined in include/crypto/internal/hash.h:
163
164::
165
166       int crypto_register_ahash(struct ahash_alg *alg);
167
168       int crypto_register_shash(struct shash_alg *alg);
169       int crypto_register_shashes(struct shash_alg *algs, int count);
170
171
172The respective counterparts for unregistering the HASH transformation
173are as follows:
174
175::
176
177       int crypto_unregister_ahash(struct ahash_alg *alg);
178
179       int crypto_unregister_shash(struct shash_alg *alg);
180       int crypto_unregister_shashes(struct shash_alg *algs, int count);
181
182
183Cipher Definition With struct shash_alg and ahash_alg
184~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186Here are schematics of how these functions are called when operated from
187other part of the kernel. Note that the .setkey() call might happen
188before or after any of these schematics happen, but must not happen
189during any of these are in-flight. Please note that calling .init()
190followed immediately by .finish() is also a perfectly valid
191transformation.
192
193::
194
195       I)   DATA -----------.
196                            v
197             .init() -> .update() -> .final()      ! .update() might not be called
198                         ^    |         |            at all in this scenario.
199                         '----'         '---> HASH
200
201       II)  DATA -----------.-----------.
202                            v           v
203             .init() -> .update() -> .finup()      ! .update() may not be called
204                         ^    |         |            at all in this scenario.
205                         '----'         '---> HASH
206
207       III) DATA -----------.
208                            v
209                        .digest()                  ! The entire process is handled
210                            |                        by the .digest() call.
211                            '---------------> HASH
212
213
214Here is a schematic of how the .export()/.import() functions are called
215when used from another part of the kernel.
216
217::
218
219       KEY--.                 DATA--.
220            v                       v                  ! .update() may not be called
221        .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
222                                 ^     |         |
223                                 '-----'         '--> PARTIAL_HASH
224
225       ----------- other transformations happen here -----------
226
227       PARTIAL_HASH--.   DATA1--.
228                     v          v
229                 .import -> .update() -> .final()     ! .update() may not be called
230                             ^    |         |           at all in this scenario.
231                             '----'         '--> HASH1
232
233       PARTIAL_HASH--.   DATA2-.
234                     v         v
235                 .import -> .finup()
236                               |
237                               '---------------> HASH2
238
239Note that it is perfectly legal to "abandon" a request object:
240- call .init() and then (as many times) .update()
241- _not_ call any of .final(), .finup() or .export() at any point in future
242
243In other words implementations should mind the resource allocation and clean-up.
244No resources related to request objects should remain allocated after a call
245to .init() or .update(), since there might be no chance to free them.
246
247
248Specifics Of Asynchronous HASH Transformation
249~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
250
251Some of the drivers will want to use the Generic ScatterWalk in case the
252implementation needs to be fed separate chunks of the scatterlist which
253contains the input data. The buffer containing the resulting hash will
254always be properly aligned to .cra_alignmask so there is no need to
255worry about this.