• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/spinlock.h>
21 // CRC fix for e307c54ac819 ("crypto: null - Use spin lock instead of mutex") requires us to put
22 // back mm.h to preserve a bunch of structure types in the crc generation logic
23 #include <linux/mm.h>
24 #include <linux/string.h>
25 
26 static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock);
27 static struct crypto_sync_skcipher *crypto_default_null_skcipher;
28 static int crypto_default_null_skcipher_refcnt;
29 
null_compress(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)30 static int null_compress(struct crypto_tfm *tfm, const u8 *src,
31 			 unsigned int slen, u8 *dst, unsigned int *dlen)
32 {
33 	if (slen > *dlen)
34 		return -EINVAL;
35 	memcpy(dst, src, slen);
36 	*dlen = slen;
37 	return 0;
38 }
39 
null_init(struct shash_desc * desc)40 static int null_init(struct shash_desc *desc)
41 {
42 	return 0;
43 }
44 
null_update(struct shash_desc * desc,const u8 * data,unsigned int len)45 static int null_update(struct shash_desc *desc, const u8 *data,
46 		       unsigned int len)
47 {
48 	return 0;
49 }
50 
null_final(struct shash_desc * desc,u8 * out)51 static int null_final(struct shash_desc *desc, u8 *out)
52 {
53 	return 0;
54 }
55 
null_digest(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)56 static int null_digest(struct shash_desc *desc, const u8 *data,
57 		       unsigned int len, u8 *out)
58 {
59 	return 0;
60 }
61 
null_hash_setkey(struct crypto_shash * tfm,const u8 * key,unsigned int keylen)62 static int null_hash_setkey(struct crypto_shash *tfm, const u8 *key,
63 			    unsigned int keylen)
64 { return 0; }
65 
null_skcipher_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)66 static int null_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
67 				unsigned int keylen)
68 { return 0; }
69 
null_setkey(struct crypto_tfm * tfm,const u8 * key,unsigned int keylen)70 static int null_setkey(struct crypto_tfm *tfm, const u8 *key,
71 		       unsigned int keylen)
72 { return 0; }
73 
null_crypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)74 static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
75 {
76 	memcpy(dst, src, NULL_BLOCK_SIZE);
77 }
78 
null_skcipher_crypt(struct skcipher_request * req)79 static int null_skcipher_crypt(struct skcipher_request *req)
80 {
81 	struct skcipher_walk walk;
82 	int err;
83 
84 	err = skcipher_walk_virt(&walk, req, false);
85 
86 	while (walk.nbytes) {
87 		if (walk.src.virt.addr != walk.dst.virt.addr)
88 			memcpy(walk.dst.virt.addr, walk.src.virt.addr,
89 			       walk.nbytes);
90 		err = skcipher_walk_done(&walk, 0);
91 	}
92 
93 	return err;
94 }
95 
96 static struct shash_alg digest_null = {
97 	.digestsize		=	NULL_DIGEST_SIZE,
98 	.setkey   		=	null_hash_setkey,
99 	.init   		=	null_init,
100 	.update 		=	null_update,
101 	.finup 			=	null_digest,
102 	.digest 		=	null_digest,
103 	.final  		=	null_final,
104 	.base			=	{
105 		.cra_name		=	"digest_null",
106 		.cra_driver_name	=	"digest_null-generic",
107 		.cra_blocksize		=	NULL_BLOCK_SIZE,
108 		.cra_module		=	THIS_MODULE,
109 	}
110 };
111 
112 static struct skcipher_alg skcipher_null = {
113 	.base.cra_name		=	"ecb(cipher_null)",
114 	.base.cra_driver_name	=	"ecb-cipher_null",
115 	.base.cra_priority	=	100,
116 	.base.cra_blocksize	=	NULL_BLOCK_SIZE,
117 	.base.cra_ctxsize	=	0,
118 	.base.cra_module	=	THIS_MODULE,
119 	.min_keysize		=	NULL_KEY_SIZE,
120 	.max_keysize		=	NULL_KEY_SIZE,
121 	.ivsize			=	NULL_IV_SIZE,
122 	.setkey			=	null_skcipher_setkey,
123 	.encrypt		=	null_skcipher_crypt,
124 	.decrypt		=	null_skcipher_crypt,
125 };
126 
127 static struct crypto_alg null_algs[] = { {
128 	.cra_name		=	"cipher_null",
129 	.cra_driver_name	=	"cipher_null-generic",
130 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
131 	.cra_blocksize		=	NULL_BLOCK_SIZE,
132 	.cra_ctxsize		=	0,
133 	.cra_module		=	THIS_MODULE,
134 	.cra_u			=	{ .cipher = {
135 	.cia_min_keysize	=	NULL_KEY_SIZE,
136 	.cia_max_keysize	=	NULL_KEY_SIZE,
137 	.cia_setkey		= 	null_setkey,
138 	.cia_encrypt		=	null_crypt,
139 	.cia_decrypt		=	null_crypt } }
140 }, {
141 	.cra_name		=	"compress_null",
142 	.cra_driver_name	=	"compress_null-generic",
143 	.cra_flags		=	CRYPTO_ALG_TYPE_COMPRESS,
144 	.cra_blocksize		=	NULL_BLOCK_SIZE,
145 	.cra_ctxsize		=	0,
146 	.cra_module		=	THIS_MODULE,
147 	.cra_u			=	{ .compress = {
148 	.coa_compress		=	null_compress,
149 	.coa_decompress		=	null_compress } }
150 } };
151 
152 MODULE_ALIAS_CRYPTO("compress_null");
153 MODULE_ALIAS_CRYPTO("digest_null");
154 MODULE_ALIAS_CRYPTO("cipher_null");
155 
crypto_get_default_null_skcipher(void)156 struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
157 {
158 	struct crypto_sync_skcipher *ntfm = NULL;
159 	struct crypto_sync_skcipher *tfm;
160 
161 	spin_lock_bh(&crypto_default_null_skcipher_lock);
162 	tfm = crypto_default_null_skcipher;
163 
164 	if (!tfm) {
165 		spin_unlock_bh(&crypto_default_null_skcipher_lock);
166 
167 		ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
168 		if (IS_ERR(ntfm))
169 			return ntfm;
170 
171 		spin_lock_bh(&crypto_default_null_skcipher_lock);
172 		tfm = crypto_default_null_skcipher;
173 		if (!tfm) {
174 			tfm = ntfm;
175 			ntfm = NULL;
176 			crypto_default_null_skcipher = tfm;
177 		}
178 	}
179 
180 	crypto_default_null_skcipher_refcnt++;
181 	spin_unlock_bh(&crypto_default_null_skcipher_lock);
182 
183 	crypto_free_sync_skcipher(ntfm);
184 
185 	return tfm;
186 }
187 EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
188 
crypto_put_default_null_skcipher(void)189 void crypto_put_default_null_skcipher(void)
190 {
191 	struct crypto_sync_skcipher *tfm = NULL;
192 
193 	spin_lock_bh(&crypto_default_null_skcipher_lock);
194 	if (!--crypto_default_null_skcipher_refcnt) {
195 		tfm = crypto_default_null_skcipher;
196 		crypto_default_null_skcipher = NULL;
197 	}
198 	spin_unlock_bh(&crypto_default_null_skcipher_lock);
199 
200 	crypto_free_sync_skcipher(tfm);
201 }
202 EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
203 
crypto_null_mod_init(void)204 static int __init crypto_null_mod_init(void)
205 {
206 	int ret = 0;
207 
208 	ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs));
209 	if (ret < 0)
210 		goto out;
211 
212 	ret = crypto_register_shash(&digest_null);
213 	if (ret < 0)
214 		goto out_unregister_algs;
215 
216 	ret = crypto_register_skcipher(&skcipher_null);
217 	if (ret < 0)
218 		goto out_unregister_shash;
219 
220 	return 0;
221 
222 out_unregister_shash:
223 	crypto_unregister_shash(&digest_null);
224 out_unregister_algs:
225 	crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
226 out:
227 	return ret;
228 }
229 
crypto_null_mod_fini(void)230 static void __exit crypto_null_mod_fini(void)
231 {
232 	crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
233 	crypto_unregister_shash(&digest_null);
234 	crypto_unregister_skcipher(&skcipher_null);
235 }
236 
237 subsys_initcall(crypto_null_mod_init);
238 module_exit(crypto_null_mod_fini);
239 
240 MODULE_LICENSE("GPL");
241 MODULE_DESCRIPTION("Null Cryptographic Algorithms");
242