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