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 skcipher_alg 132~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 134Struct skcipher_alg defines a multi-block cipher, or more generally, a 135length-preserving symmetric cipher algorithm. 136 137Scatterlist handling 138~~~~~~~~~~~~~~~~~~~~ 139 140Some drivers will want to use the Generic ScatterWalk in case the 141hardware needs to be fed separate chunks of the scatterlist which 142contains the plaintext and will contain the ciphertext. Please refer 143to the ScatterWalk interface offered by the Linux kernel scatter / 144gather list implementation. 145 146Hashing [HASH] 147-------------- 148 149Example of transformations: crc32, md5, sha1, sha256,... 150 151Registering And Unregistering The Transformation 152~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 153 154There are multiple ways to register a HASH transformation, depending on 155whether the transformation is synchronous [SHASH] or asynchronous 156[AHASH] and the amount of HASH transformations we are registering. You 157can find the prototypes defined in include/crypto/internal/hash.h: 158 159:: 160 161 int crypto_register_ahash(struct ahash_alg *alg); 162 163 int crypto_register_shash(struct shash_alg *alg); 164 int crypto_register_shashes(struct shash_alg *algs, int count); 165 166 167The respective counterparts for unregistering the HASH transformation 168are as follows: 169 170:: 171 172 int crypto_unregister_ahash(struct ahash_alg *alg); 173 174 int crypto_unregister_shash(struct shash_alg *alg); 175 int crypto_unregister_shashes(struct shash_alg *algs, int count); 176 177 178Cipher Definition With struct shash_alg and ahash_alg 179~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 180 181Here are schematics of how these functions are called when operated from 182other part of the kernel. Note that the .setkey() call might happen 183before or after any of these schematics happen, but must not happen 184during any of these are in-flight. Please note that calling .init() 185followed immediately by .finish() is also a perfectly valid 186transformation. 187 188:: 189 190 I) DATA -----------. 191 v 192 .init() -> .update() -> .final() ! .update() might not be called 193 ^ | | at all in this scenario. 194 '----' '---> HASH 195 196 II) DATA -----------.-----------. 197 v v 198 .init() -> .update() -> .finup() ! .update() may not be called 199 ^ | | at all in this scenario. 200 '----' '---> HASH 201 202 III) DATA -----------. 203 v 204 .digest() ! The entire process is handled 205 | by the .digest() call. 206 '---------------> HASH 207 208 209Here is a schematic of how the .export()/.import() functions are called 210when used from another part of the kernel. 211 212:: 213 214 KEY--. DATA--. 215 v v ! .update() may not be called 216 .setkey() -> .init() -> .update() -> .export() at all in this scenario. 217 ^ | | 218 '-----' '--> PARTIAL_HASH 219 220 ----------- other transformations happen here ----------- 221 222 PARTIAL_HASH--. DATA1--. 223 v v 224 .import -> .update() -> .final() ! .update() may not be called 225 ^ | | at all in this scenario. 226 '----' '--> HASH1 227 228 PARTIAL_HASH--. DATA2-. 229 v v 230 .import -> .finup() 231 | 232 '---------------> HASH2 233 234Note that it is perfectly legal to "abandon" a request object: 235- call .init() and then (as many times) .update() 236- _not_ call any of .final(), .finup() or .export() at any point in future 237 238In other words implementations should mind the resource allocation and clean-up. 239No resources related to request objects should remain allocated after a call 240to .init() or .update(), since there might be no chance to free them. 241 242 243Specifics Of Asynchronous HASH Transformation 244~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 245 246Some of the drivers will want to use the Generic ScatterWalk in case the 247implementation needs to be fed separate chunks of the scatterlist which 248contains the input data. The buffer containing the resulting hash will 249always be properly aligned to .cra_alignmask so there is no need to 250worry about this. 251