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 1 : static int __init crypto_null_mod_init(void)
189 : {
190 1 : int ret = 0;
191 :
192 1 : ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs));
193 1 : if (ret < 0)
194 0 : goto out;
195 :
196 1 : ret = crypto_register_shash(&digest_null);
197 1 : if (ret < 0)
198 0 : goto out_unregister_algs;
199 :
200 1 : ret = crypto_register_skcipher(&skcipher_null);
201 1 : if (ret < 0)
202 0 : goto out_unregister_shash;
203 :
204 : return 0;
205 :
206 0 : 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");
|