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 : : struct skcipher_walk walk; 79 : : 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 : : 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 : : goto unlock; 164 : : 165 : 0 : crypto_default_null_skcipher = tfm; 166 : : } 167 : : 168 : 0 : crypto_default_null_skcipher_refcnt++; 169 : : 170 : : 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 : 3 : static int __init crypto_null_mod_init(void) 189 : : { 190 : : int ret = 0; 191 : : 192 : 3 : ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs)); 193 : 3 : if (ret < 0) 194 : : goto out; 195 : : 196 : 3 : ret = crypto_register_shash(&digest_null); 197 : 3 : if (ret < 0) 198 : : goto out_unregister_algs; 199 : : 200 : 3 : ret = crypto_register_skcipher(&skcipher_null); 201 : 3 : if (ret < 0) 202 : : goto out_unregister_shash; 203 : : 204 : : return 0; 205 : : 206 : : out_unregister_shash: 207 : 0 : crypto_unregister_shash(&digest_null); 208 : : out_unregister_algs: 209 : 0 : crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs)); 210 : : out: 211 : 0 : 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");