Back to home page

OSCL-LXR

 
 

    


0001 Developing Cipher Algorithms
0002 ============================
0003 
0004 Registering And Unregistering Transformation
0005 --------------------------------------------
0006 
0007 There are three distinct types of registration functions in the Crypto
0008 API. One is used to register a generic cryptographic transformation,
0009 while the other two are specific to HASH transformations and
0010 COMPRESSion. We will discuss the latter two in a separate chapter, here
0011 we will only look at the generic ones.
0012 
0013 Before discussing the register functions, the data structure to be
0014 filled with each, struct crypto_alg, must be considered -- see below
0015 for a description of this data structure.
0016 
0017 The generic registration functions can be found in
0018 include/linux/crypto.h and their definition can be seen below. The
0019 former function registers a single transformation, while the latter
0020 works on an array of transformation descriptions. The latter is useful
0021 when registering transformations in bulk, for example when a driver
0022 implements multiple transformations.
0023 
0024 ::
0025 
0026        int crypto_register_alg(struct crypto_alg *alg);
0027        int crypto_register_algs(struct crypto_alg *algs, int count);
0028 
0029 
0030 The counterparts to those functions are listed below.
0031 
0032 ::
0033 
0034        void crypto_unregister_alg(struct crypto_alg *alg);
0035        void crypto_unregister_algs(struct crypto_alg *algs, int count);
0036 
0037 
0038 The registration functions return 0 on success, or a negative errno
0039 value on failure.  crypto_register_algs() succeeds only if it
0040 successfully registered all the given algorithms; if it fails partway
0041 through, then any changes are rolled back.
0042 
0043 The unregistration functions always succeed, so they don't have a
0044 return value.  Don't try to unregister algorithms that aren't
0045 currently registered.
0046 
0047 Single-Block Symmetric Ciphers [CIPHER]
0048 ---------------------------------------
0049 
0050 Example of transformations: aes, serpent, ...
0051 
0052 This section describes the simplest of all transformation
0053 implementations, that being the CIPHER type used for symmetric ciphers.
0054 The CIPHER type is used for transformations which operate on exactly one
0055 block at a time and there are no dependencies between blocks at all.
0056 
0057 Registration specifics
0058 ~~~~~~~~~~~~~~~~~~~~~~
0059 
0060 The registration of [CIPHER] algorithm is specific in that struct
0061 crypto_alg field .cra_type is empty. The .cra_u.cipher has to be
0062 filled in with proper callbacks to implement this transformation.
0063 
0064 See struct cipher_alg below.
0065 
0066 Cipher Definition With struct cipher_alg
0067 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0068 
0069 Struct cipher_alg defines a single block cipher.
0070 
0071 Here are schematics of how these functions are called when operated from
0072 other part of the kernel. Note that the .cia_setkey() call might happen
0073 before or after any of these schematics happen, but must not happen
0074 during any of these are in-flight.
0075 
0076 ::
0077 
0078              KEY ---.    PLAINTEXT ---.
0079                     v                 v
0080               .cia_setkey() -> .cia_encrypt()
0081                                       |
0082                                       '-----> CIPHERTEXT
0083 
0084 
0085 Please note that a pattern where .cia_setkey() is called multiple times
0086 is also valid:
0087 
0088 ::
0089 
0090 
0091       KEY1 --.    PLAINTEXT1 --.         KEY2 --.    PLAINTEXT2 --.
0092              v                 v                v                 v
0093        .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
0094                                |                                  |
0095                                '---> CIPHERTEXT1                  '---> CIPHERTEXT2
0096 
0097 
0098 Multi-Block Ciphers
0099 -------------------
0100 
0101 Example of transformations: cbc(aes), chacha20, ...
0102 
0103 This section describes the multi-block cipher transformation
0104 implementations. The multi-block ciphers are used for transformations
0105 which operate on scatterlists of data supplied to the transformation
0106 functions. They output the result into a scatterlist of data as well.
0107 
0108 Registration Specifics
0109 ~~~~~~~~~~~~~~~~~~~~~~
0110 
0111 The registration of multi-block cipher algorithms is one of the most
0112 standard procedures throughout the crypto API.
0113 
0114 Note, if a cipher implementation requires a proper alignment of data,
0115 the caller should use the functions of crypto_skcipher_alignmask() to
0116 identify a memory alignment mask. The kernel crypto API is able to
0117 process requests that are unaligned. This implies, however, additional
0118 overhead as the kernel crypto API needs to perform the realignment of
0119 the data which may imply moving of data.
0120 
0121 Cipher Definition With struct skcipher_alg
0122 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0123 
0124 Struct skcipher_alg defines a multi-block cipher, or more generally, a
0125 length-preserving symmetric cipher algorithm.
0126 
0127 Scatterlist handling
0128 ~~~~~~~~~~~~~~~~~~~~
0129 
0130 Some drivers will want to use the Generic ScatterWalk in case the
0131 hardware needs to be fed separate chunks of the scatterlist which
0132 contains the plaintext and will contain the ciphertext. Please refer
0133 to the ScatterWalk interface offered by the Linux kernel scatter /
0134 gather list implementation.
0135 
0136 Hashing [HASH]
0137 --------------
0138 
0139 Example of transformations: crc32, md5, sha1, sha256,...
0140 
0141 Registering And Unregistering The Transformation
0142 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0143 
0144 There are multiple ways to register a HASH transformation, depending on
0145 whether the transformation is synchronous [SHASH] or asynchronous
0146 [AHASH] and the amount of HASH transformations we are registering. You
0147 can find the prototypes defined in include/crypto/internal/hash.h:
0148 
0149 ::
0150 
0151        int crypto_register_ahash(struct ahash_alg *alg);
0152 
0153        int crypto_register_shash(struct shash_alg *alg);
0154        int crypto_register_shashes(struct shash_alg *algs, int count);
0155 
0156 
0157 The respective counterparts for unregistering the HASH transformation
0158 are as follows:
0159 
0160 ::
0161 
0162        void crypto_unregister_ahash(struct ahash_alg *alg);
0163 
0164        void crypto_unregister_shash(struct shash_alg *alg);
0165        void crypto_unregister_shashes(struct shash_alg *algs, int count);
0166 
0167 
0168 Cipher Definition With struct shash_alg and ahash_alg
0169 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0170 
0171 Here are schematics of how these functions are called when operated from
0172 other part of the kernel. Note that the .setkey() call might happen
0173 before or after any of these schematics happen, but must not happen
0174 during any of these are in-flight. Please note that calling .init()
0175 followed immediately by .finish() is also a perfectly valid
0176 transformation.
0177 
0178 ::
0179 
0180        I)   DATA -----------.
0181                             v
0182              .init() -> .update() -> .final()      ! .update() might not be called
0183                          ^    |         |            at all in this scenario.
0184                          '----'         '---> HASH
0185 
0186        II)  DATA -----------.-----------.
0187                             v           v
0188              .init() -> .update() -> .finup()      ! .update() may not be called
0189                          ^    |         |            at all in this scenario.
0190                          '----'         '---> HASH
0191 
0192        III) DATA -----------.
0193                             v
0194                         .digest()                  ! The entire process is handled
0195                             |                        by the .digest() call.
0196                             '---------------> HASH
0197 
0198 
0199 Here is a schematic of how the .export()/.import() functions are called
0200 when used from another part of the kernel.
0201 
0202 ::
0203 
0204        KEY--.                 DATA--.
0205             v                       v                  ! .update() may not be called
0206         .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
0207                                  ^     |         |
0208                                  '-----'         '--> PARTIAL_HASH
0209 
0210        ----------- other transformations happen here -----------
0211 
0212        PARTIAL_HASH--.   DATA1--.
0213                      v          v
0214                  .import -> .update() -> .final()     ! .update() may not be called
0215                              ^    |         |           at all in this scenario.
0216                              '----'         '--> HASH1
0217 
0218        PARTIAL_HASH--.   DATA2-.
0219                      v         v
0220                  .import -> .finup()
0221                                |
0222                                '---------------> HASH2
0223 
0224 Note that it is perfectly legal to "abandon" a request object:
0225 - call .init() and then (as many times) .update()
0226 - _not_ call any of .final(), .finup() or .export() at any point in future
0227 
0228 In other words implementations should mind the resource allocation and clean-up.
0229 No resources related to request objects should remain allocated after a call
0230 to .init() or .update(), since there might be no chance to free them.
0231 
0232 
0233 Specifics Of Asynchronous HASH Transformation
0234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0235 
0236 Some of the drivers will want to use the Generic ScatterWalk in case the
0237 implementation needs to be fed separate chunks of the scatterlist which
0238 contains the input data. The buffer containing the resulting hash will
0239 always be properly aligned to .cra_alignmask so there is no need to
0240 worry about this.