18c2ecf20Sopenharmony_ciDeveloping Cipher Algorithms
28c2ecf20Sopenharmony_ci============================
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ciRegistering And Unregistering Transformation
58c2ecf20Sopenharmony_ci--------------------------------------------
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciThere are three distinct types of registration functions in the Crypto
88c2ecf20Sopenharmony_ciAPI. One is used to register a generic cryptographic transformation,
98c2ecf20Sopenharmony_ciwhile the other two are specific to HASH transformations and
108c2ecf20Sopenharmony_ciCOMPRESSion. We will discuss the latter two in a separate chapter, here
118c2ecf20Sopenharmony_ciwe will only look at the generic ones.
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciBefore discussing the register functions, the data structure to be
148c2ecf20Sopenharmony_cifilled with each, struct crypto_alg, must be considered -- see below
158c2ecf20Sopenharmony_cifor a description of this data structure.
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciThe generic registration functions can be found in
188c2ecf20Sopenharmony_ciinclude/linux/crypto.h and their definition can be seen below. The
198c2ecf20Sopenharmony_ciformer function registers a single transformation, while the latter
208c2ecf20Sopenharmony_ciworks on an array of transformation descriptions. The latter is useful
218c2ecf20Sopenharmony_ciwhen registering transformations in bulk, for example when a driver
228c2ecf20Sopenharmony_ciimplements multiple transformations.
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci::
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci       int crypto_register_alg(struct crypto_alg *alg);
278c2ecf20Sopenharmony_ci       int crypto_register_algs(struct crypto_alg *algs, int count);
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciThe counterparts to those functions are listed below.
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci::
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci       void crypto_unregister_alg(struct crypto_alg *alg);
358c2ecf20Sopenharmony_ci       void crypto_unregister_algs(struct crypto_alg *algs, int count);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ciThe registration functions return 0 on success, or a negative errno
398c2ecf20Sopenharmony_civalue on failure.  crypto_register_algs() succeeds only if it
408c2ecf20Sopenharmony_cisuccessfully registered all the given algorithms; if it fails partway
418c2ecf20Sopenharmony_cithrough, then any changes are rolled back.
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciThe unregistration functions always succeed, so they don't have a
448c2ecf20Sopenharmony_cireturn value.  Don't try to unregister algorithms that aren't
458c2ecf20Sopenharmony_cicurrently registered.
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciSingle-Block Symmetric Ciphers [CIPHER]
488c2ecf20Sopenharmony_ci---------------------------------------
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciExample of transformations: aes, serpent, ...
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ciThis section describes the simplest of all transformation
538c2ecf20Sopenharmony_ciimplementations, that being the CIPHER type used for symmetric ciphers.
548c2ecf20Sopenharmony_ciThe CIPHER type is used for transformations which operate on exactly one
558c2ecf20Sopenharmony_ciblock at a time and there are no dependencies between blocks at all.
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciRegistration specifics
588c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciThe registration of [CIPHER] algorithm is specific in that struct
618c2ecf20Sopenharmony_cicrypto_alg field .cra_type is empty. The .cra_u.cipher has to be
628c2ecf20Sopenharmony_cifilled in with proper callbacks to implement this transformation.
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciSee struct cipher_alg below.
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciCipher Definition With struct cipher_alg
678c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ciStruct cipher_alg defines a single block cipher.
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ciHere are schematics of how these functions are called when operated from
728c2ecf20Sopenharmony_ciother part of the kernel. Note that the .cia_setkey() call might happen
738c2ecf20Sopenharmony_cibefore or after any of these schematics happen, but must not happen
748c2ecf20Sopenharmony_ciduring any of these are in-flight.
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci::
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci             KEY ---.    PLAINTEXT ---.
798c2ecf20Sopenharmony_ci                    v                 v
808c2ecf20Sopenharmony_ci              .cia_setkey() -> .cia_encrypt()
818c2ecf20Sopenharmony_ci                                      |
828c2ecf20Sopenharmony_ci                                      '-----> CIPHERTEXT
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciPlease note that a pattern where .cia_setkey() is called multiple times
868c2ecf20Sopenharmony_ciis also valid:
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci::
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci      KEY1 --.    PLAINTEXT1 --.         KEY2 --.    PLAINTEXT2 --.
928c2ecf20Sopenharmony_ci             v                 v                v                 v
938c2ecf20Sopenharmony_ci       .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
948c2ecf20Sopenharmony_ci                               |                                  |
958c2ecf20Sopenharmony_ci                               '---> CIPHERTEXT1                  '---> CIPHERTEXT2
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciMulti-Block Ciphers
998c2ecf20Sopenharmony_ci-------------------
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciExample of transformations: cbc(aes), chacha20, ...
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ciThis section describes the multi-block cipher transformation
1048c2ecf20Sopenharmony_ciimplementations. The multi-block ciphers are used for transformations
1058c2ecf20Sopenharmony_ciwhich operate on scatterlists of data supplied to the transformation
1068c2ecf20Sopenharmony_cifunctions. They output the result into a scatterlist of data as well.
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ciRegistration Specifics
1098c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ciThe registration of multi-block cipher algorithms is one of the most
1128c2ecf20Sopenharmony_cistandard procedures throughout the crypto API.
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ciNote, if a cipher implementation requires a proper alignment of data,
1158c2ecf20Sopenharmony_cithe caller should use the functions of crypto_skcipher_alignmask() to
1168c2ecf20Sopenharmony_ciidentify a memory alignment mask. The kernel crypto API is able to
1178c2ecf20Sopenharmony_ciprocess requests that are unaligned. This implies, however, additional
1188c2ecf20Sopenharmony_cioverhead as the kernel crypto API needs to perform the realignment of
1198c2ecf20Sopenharmony_cithe data which may imply moving of data.
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ciCipher Definition With struct skcipher_alg
1228c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ciStruct skcipher_alg defines a multi-block cipher, or more generally, a
1258c2ecf20Sopenharmony_cilength-preserving symmetric cipher algorithm.
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ciScatterlist handling
1288c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ciSome drivers will want to use the Generic ScatterWalk in case the
1318c2ecf20Sopenharmony_cihardware needs to be fed separate chunks of the scatterlist which
1328c2ecf20Sopenharmony_cicontains the plaintext and will contain the ciphertext. Please refer
1338c2ecf20Sopenharmony_cito the ScatterWalk interface offered by the Linux kernel scatter /
1348c2ecf20Sopenharmony_cigather list implementation.
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ciHashing [HASH]
1378c2ecf20Sopenharmony_ci--------------
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ciExample of transformations: crc32, md5, sha1, sha256,...
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciRegistering And Unregistering The Transformation
1428c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ciThere are multiple ways to register a HASH transformation, depending on
1458c2ecf20Sopenharmony_ciwhether the transformation is synchronous [SHASH] or asynchronous
1468c2ecf20Sopenharmony_ci[AHASH] and the amount of HASH transformations we are registering. You
1478c2ecf20Sopenharmony_cican find the prototypes defined in include/crypto/internal/hash.h:
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci::
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci       int crypto_register_ahash(struct ahash_alg *alg);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci       int crypto_register_shash(struct shash_alg *alg);
1548c2ecf20Sopenharmony_ci       int crypto_register_shashes(struct shash_alg *algs, int count);
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ciThe respective counterparts for unregistering the HASH transformation
1588c2ecf20Sopenharmony_ciare as follows:
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci::
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci       void crypto_unregister_ahash(struct ahash_alg *alg);
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci       void crypto_unregister_shash(struct shash_alg *alg);
1658c2ecf20Sopenharmony_ci       void crypto_unregister_shashes(struct shash_alg *algs, int count);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ciCipher Definition With struct shash_alg and ahash_alg
1698c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ciHere are schematics of how these functions are called when operated from
1728c2ecf20Sopenharmony_ciother part of the kernel. Note that the .setkey() call might happen
1738c2ecf20Sopenharmony_cibefore or after any of these schematics happen, but must not happen
1748c2ecf20Sopenharmony_ciduring any of these are in-flight. Please note that calling .init()
1758c2ecf20Sopenharmony_cifollowed immediately by .finish() is also a perfectly valid
1768c2ecf20Sopenharmony_citransformation.
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci::
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci       I)   DATA -----------.
1818c2ecf20Sopenharmony_ci                            v
1828c2ecf20Sopenharmony_ci             .init() -> .update() -> .final()      ! .update() might not be called
1838c2ecf20Sopenharmony_ci                         ^    |         |            at all in this scenario.
1848c2ecf20Sopenharmony_ci                         '----'         '---> HASH
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci       II)  DATA -----------.-----------.
1878c2ecf20Sopenharmony_ci                            v           v
1888c2ecf20Sopenharmony_ci             .init() -> .update() -> .finup()      ! .update() may not be called
1898c2ecf20Sopenharmony_ci                         ^    |         |            at all in this scenario.
1908c2ecf20Sopenharmony_ci                         '----'         '---> HASH
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci       III) DATA -----------.
1938c2ecf20Sopenharmony_ci                            v
1948c2ecf20Sopenharmony_ci                        .digest()                  ! The entire process is handled
1958c2ecf20Sopenharmony_ci                            |                        by the .digest() call.
1968c2ecf20Sopenharmony_ci                            '---------------> HASH
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ciHere is a schematic of how the .export()/.import() functions are called
2008c2ecf20Sopenharmony_ciwhen used from another part of the kernel.
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci::
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci       KEY--.                 DATA--.
2058c2ecf20Sopenharmony_ci            v                       v                  ! .update() may not be called
2068c2ecf20Sopenharmony_ci        .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
2078c2ecf20Sopenharmony_ci                                 ^     |         |
2088c2ecf20Sopenharmony_ci                                 '-----'         '--> PARTIAL_HASH
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci       ----------- other transformations happen here -----------
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci       PARTIAL_HASH--.   DATA1--.
2138c2ecf20Sopenharmony_ci                     v          v
2148c2ecf20Sopenharmony_ci                 .import -> .update() -> .final()     ! .update() may not be called
2158c2ecf20Sopenharmony_ci                             ^    |         |           at all in this scenario.
2168c2ecf20Sopenharmony_ci                             '----'         '--> HASH1
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci       PARTIAL_HASH--.   DATA2-.
2198c2ecf20Sopenharmony_ci                     v         v
2208c2ecf20Sopenharmony_ci                 .import -> .finup()
2218c2ecf20Sopenharmony_ci                               |
2228c2ecf20Sopenharmony_ci                               '---------------> HASH2
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ciNote that it is perfectly legal to "abandon" a request object:
2258c2ecf20Sopenharmony_ci- call .init() and then (as many times) .update()
2268c2ecf20Sopenharmony_ci- _not_ call any of .final(), .finup() or .export() at any point in future
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ciIn other words implementations should mind the resource allocation and clean-up.
2298c2ecf20Sopenharmony_ciNo resources related to request objects should remain allocated after a call
2308c2ecf20Sopenharmony_cito .init() or .update(), since there might be no chance to free them.
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ciSpecifics Of Asynchronous HASH Transformation
2348c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ciSome of the drivers will want to use the Generic ScatterWalk in case the
2378c2ecf20Sopenharmony_ciimplementation needs to be fed separate chunks of the scatterlist which
2388c2ecf20Sopenharmony_cicontains the input data. The buffer containing the resulting hash will
2398c2ecf20Sopenharmony_cialways be properly aligned to .cra_alignmask so there is no need to
2408c2ecf20Sopenharmony_ciworry about this.
241