Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * Cryptographic API.
4 : : *
5 : : * Null algorithms, aka Much Ado About Nothing.
6 : : *
7 : : * These are needed for IPsec, and may be useful in general for
8 : : * testing & debugging.
9 : : *
10 : : * The null cipher is compliant with RFC2410.
11 : : *
12 : : * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
13 : : */
14 : :
15 : : #include <crypto/null.h>
16 : : #include <crypto/internal/hash.h>
17 : : #include <crypto/internal/skcipher.h>
18 : : #include <linux/init.h>
19 : : #include <linux/module.h>
20 : : #include <linux/mm.h>
21 : : #include <linux/string.h>
22 : :
23 : : static DEFINE_MUTEX(crypto_default_null_skcipher_lock);
24 : : static struct crypto_sync_skcipher *crypto_default_null_skcipher;
25 : : static int crypto_default_null_skcipher_refcnt;
26 : :
27 : 0 : static int null_compress(struct crypto_tfm *tfm, const u8 *src,
28 : : unsigned int slen, u8 *dst, unsigned int *dlen)
29 : : {
30 [ # # ]: 0 : if (slen > *dlen)
31 : : return -EINVAL;
32 : 0 : memcpy(dst, src, slen);
33 : 0 : *dlen = slen;
34 : 0 : return 0;
35 : : }
36 : :
37 : 0 : static int null_init(struct shash_desc *desc)
38 : : {
39 : 0 : return 0;
40 : : }
41 : :
42 : 0 : static int null_update(struct shash_desc *desc, const u8 *data,
43 : : unsigned int len)
44 : : {
45 : 0 : return 0;
46 : : }
47 : :
48 : 0 : static int null_final(struct shash_desc *desc, u8 *out)
49 : : {
50 : 0 : return 0;
51 : : }
52 : :
53 : 0 : static int null_digest(struct shash_desc *desc, const u8 *data,
54 : : unsigned int len, u8 *out)
55 : : {
56 : 0 : return 0;
57 : : }
58 : :
59 : 0 : static int null_hash_setkey(struct crypto_shash *tfm, const u8 *key,
60 : : unsigned int keylen)
61 : 0 : { return 0; }
62 : :
63 : 0 : static int null_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
64 : : unsigned int keylen)
65 : 0 : { return 0; }
66 : :
67 : 0 : static int null_setkey(struct crypto_tfm *tfm, const u8 *key,
68 : : unsigned int keylen)
69 : 0 : { return 0; }
70 : :
71 : 0 : static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
72 : : {
73 : 0 : memcpy(dst, src, NULL_BLOCK_SIZE);
74 : 0 : }
75 : :
76 : 0 : static int null_skcipher_crypt(struct skcipher_request *req)
77 : : {
78 : 0 : struct skcipher_walk walk;
79 : 0 : int err;
80 : :
81 : 0 : err = skcipher_walk_virt(&walk, req, false);
82 : :
83 [ # # ]: 0 : while (walk.nbytes) {
84 [ # # ]: 0 : if (walk.src.virt.addr != walk.dst.virt.addr)
85 : 0 : memcpy(walk.dst.virt.addr, walk.src.virt.addr,
86 : : walk.nbytes);
87 : 0 : err = skcipher_walk_done(&walk, 0);
88 : : }
89 : :
90 : 0 : return err;
91 : : }
92 : :
93 : : static struct shash_alg digest_null = {
94 : : .digestsize = NULL_DIGEST_SIZE,
95 : : .setkey = null_hash_setkey,
96 : : .init = null_init,
97 : : .update = null_update,
98 : : .finup = null_digest,
99 : : .digest = null_digest,
100 : : .final = null_final,
101 : : .base = {
102 : : .cra_name = "digest_null",
103 : : .cra_driver_name = "digest_null-generic",
104 : : .cra_blocksize = NULL_BLOCK_SIZE,
105 : : .cra_module = THIS_MODULE,
106 : : }
107 : : };
108 : :
109 : : static struct skcipher_alg skcipher_null = {
110 : : .base.cra_name = "ecb(cipher_null)",
111 : : .base.cra_driver_name = "ecb-cipher_null",
112 : : .base.cra_priority = 100,
113 : : .base.cra_blocksize = NULL_BLOCK_SIZE,
114 : : .base.cra_ctxsize = 0,
115 : : .base.cra_module = THIS_MODULE,
116 : : .min_keysize = NULL_KEY_SIZE,
117 : : .max_keysize = NULL_KEY_SIZE,
118 : : .ivsize = NULL_IV_SIZE,
119 : : .setkey = null_skcipher_setkey,
120 : : .encrypt = null_skcipher_crypt,
121 : : .decrypt = null_skcipher_crypt,
122 : : };
123 : :
124 : : static struct crypto_alg null_algs[] = { {
125 : : .cra_name = "cipher_null",
126 : : .cra_driver_name = "cipher_null-generic",
127 : : .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
128 : : .cra_blocksize = NULL_BLOCK_SIZE,
129 : : .cra_ctxsize = 0,
130 : : .cra_module = THIS_MODULE,
131 : : .cra_u = { .cipher = {
132 : : .cia_min_keysize = NULL_KEY_SIZE,
133 : : .cia_max_keysize = NULL_KEY_SIZE,
134 : : .cia_setkey = null_setkey,
135 : : .cia_encrypt = null_crypt,
136 : : .cia_decrypt = null_crypt } }
137 : : }, {
138 : : .cra_name = "compress_null",
139 : : .cra_driver_name = "compress_null-generic",
140 : : .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
141 : : .cra_blocksize = NULL_BLOCK_SIZE,
142 : : .cra_ctxsize = 0,
143 : : .cra_module = THIS_MODULE,
144 : : .cra_u = { .compress = {
145 : : .coa_compress = null_compress,
146 : : .coa_decompress = null_compress } }
147 : : } };
148 : :
149 : : MODULE_ALIAS_CRYPTO("compress_null");
150 : : MODULE_ALIAS_CRYPTO("digest_null");
151 : : MODULE_ALIAS_CRYPTO("cipher_null");
152 : :
153 : 0 : struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
154 : : {
155 : 0 : struct crypto_sync_skcipher *tfm;
156 : :
157 : 0 : mutex_lock(&crypto_default_null_skcipher_lock);
158 : 0 : tfm = crypto_default_null_skcipher;
159 : :
160 [ # # ]: 0 : if (!tfm) {
161 : 0 : tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
162 [ # # ]: 0 : if (IS_ERR(tfm))
163 : 0 : goto unlock;
164 : :
165 : 0 : crypto_default_null_skcipher = tfm;
166 : : }
167 : :
168 : 0 : crypto_default_null_skcipher_refcnt++;
169 : :
170 : 0 : unlock:
171 : 0 : mutex_unlock(&crypto_default_null_skcipher_lock);
172 : :
173 : 0 : return tfm;
174 : : }
175 : : EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
176 : :
177 : 0 : void crypto_put_default_null_skcipher(void)
178 : : {
179 : 0 : mutex_lock(&crypto_default_null_skcipher_lock);
180 [ # # ]: 0 : if (!--crypto_default_null_skcipher_refcnt) {
181 : 0 : crypto_free_sync_skcipher(crypto_default_null_skcipher);
182 : 0 : crypto_default_null_skcipher = NULL;
183 : : }
184 : 0 : mutex_unlock(&crypto_default_null_skcipher_lock);
185 : 0 : }
186 : : EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
187 : :
188 : 13 : static int __init crypto_null_mod_init(void)
189 : : {
190 : 13 : int ret = 0;
191 : :
192 : 13 : ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs));
193 [ - + ]: 13 : if (ret < 0)
194 : 0 : goto out;
195 : :
196 : 13 : ret = crypto_register_shash(&digest_null);
197 [ - + ]: 13 : if (ret < 0)
198 : 0 : goto out_unregister_algs;
199 : :
200 : 13 : ret = crypto_register_skcipher(&skcipher_null);
201 [ - + ]: 13 : if (ret < 0)
202 : 0 : goto out_unregister_shash;
203 : :
204 : : return 0;
205 : :
206 : : out_unregister_shash:
207 : 0 : crypto_unregister_shash(&digest_null);
208 : 0 : out_unregister_algs:
209 : 0 : crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
210 : : out:
211 : : return ret;
212 : : }
213 : :
214 : 0 : static void __exit crypto_null_mod_fini(void)
215 : : {
216 : 0 : crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
217 : 0 : crypto_unregister_shash(&digest_null);
218 : 0 : crypto_unregister_skcipher(&skcipher_null);
219 : 0 : }
220 : :
221 : : subsys_initcall(crypto_null_mod_init);
222 : : module_exit(crypto_null_mod_fini);
223 : :
224 : : MODULE_LICENSE("GPL");
225 : : MODULE_DESCRIPTION("Null Cryptographic Algorithms");
|