devel-algos.rst (8991B)
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 .finish() 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. The buffer containing the resulting hash will 239always be properly aligned to .cra_alignmask so there is no need to 240worry about this.