11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Cryptographic API. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Null algorithms, aka Much Ado About Nothing. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * These are needed for IPsec, and may be useful in general for 71da177e4SLinus Torvalds * testing & debugging. 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * The null cipher is compliant with RFC2410. 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 141da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 151da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 161da177e4SLinus Torvalds * (at your option) any later version. 171da177e4SLinus Torvalds * 181da177e4SLinus Torvalds */ 193631c650SHerbert Xu 2072567258SHoria Geanta #include <crypto/null.h> 21d35d2454SHerbert Xu #include <crypto/internal/hash.h> 223631c650SHerbert Xu #include <crypto/internal/skcipher.h> 231da177e4SLinus Torvalds #include <linux/init.h> 241da177e4SLinus Torvalds #include <linux/module.h> 251da177e4SLinus Torvalds #include <linux/mm.h> 26d0856009SPatrick McHardy #include <linux/string.h> 271da177e4SLinus Torvalds 2833023463SHerbert Xu static DEFINE_MUTEX(crypto_default_null_skcipher_lock); 2933023463SHerbert Xu static struct crypto_blkcipher *crypto_default_null_skcipher; 3033023463SHerbert Xu static int crypto_default_null_skcipher_refcnt; 3133023463SHerbert Xu 326c2bb98bSHerbert Xu static int null_compress(struct crypto_tfm *tfm, const u8 *src, 336c2bb98bSHerbert Xu unsigned int slen, u8 *dst, unsigned int *dlen) 34d0856009SPatrick McHardy { 35d0856009SPatrick McHardy if (slen > *dlen) 36d0856009SPatrick McHardy return -EINVAL; 37d0856009SPatrick McHardy memcpy(dst, src, slen); 38d0856009SPatrick McHardy *dlen = slen; 39d0856009SPatrick McHardy return 0; 40d0856009SPatrick McHardy } 411da177e4SLinus Torvalds 42d35d2454SHerbert Xu static int null_init(struct shash_desc *desc) 43d35d2454SHerbert Xu { 44d35d2454SHerbert Xu return 0; 45d35d2454SHerbert Xu } 461da177e4SLinus Torvalds 47d35d2454SHerbert Xu static int null_update(struct shash_desc *desc, const u8 *data, 486c2bb98bSHerbert Xu unsigned int len) 49d35d2454SHerbert Xu { 50d35d2454SHerbert Xu return 0; 51d35d2454SHerbert Xu } 521da177e4SLinus Torvalds 53d35d2454SHerbert Xu static int null_final(struct shash_desc *desc, u8 *out) 54d35d2454SHerbert Xu { 55d35d2454SHerbert Xu return 0; 56d35d2454SHerbert Xu } 57d35d2454SHerbert Xu 58d35d2454SHerbert Xu static int null_digest(struct shash_desc *desc, const u8 *data, 59d35d2454SHerbert Xu unsigned int len, u8 *out) 60d35d2454SHerbert Xu { 61d35d2454SHerbert Xu return 0; 62d35d2454SHerbert Xu } 63d35d2454SHerbert Xu 64d35d2454SHerbert Xu static int null_hash_setkey(struct crypto_shash *tfm, const u8 *key, 65d35d2454SHerbert Xu unsigned int keylen) 66d35d2454SHerbert Xu { return 0; } 671da177e4SLinus Torvalds 686c2bb98bSHerbert Xu static int null_setkey(struct crypto_tfm *tfm, const u8 *key, 69560c06aeSHerbert Xu unsigned int keylen) 701da177e4SLinus Torvalds { return 0; } 711da177e4SLinus Torvalds 726c2bb98bSHerbert Xu static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 73d0856009SPatrick McHardy { 74d0856009SPatrick McHardy memcpy(dst, src, NULL_BLOCK_SIZE); 75d0856009SPatrick McHardy } 761da177e4SLinus Torvalds 773631c650SHerbert Xu static int skcipher_null_crypt(struct blkcipher_desc *desc, 783631c650SHerbert Xu struct scatterlist *dst, 793631c650SHerbert Xu struct scatterlist *src, unsigned int nbytes) 803631c650SHerbert Xu { 813631c650SHerbert Xu struct blkcipher_walk walk; 823631c650SHerbert Xu int err; 833631c650SHerbert Xu 843631c650SHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 853631c650SHerbert Xu err = blkcipher_walk_virt(desc, &walk); 863631c650SHerbert Xu 873631c650SHerbert Xu while (walk.nbytes) { 883631c650SHerbert Xu if (walk.src.virt.addr != walk.dst.virt.addr) 893631c650SHerbert Xu memcpy(walk.dst.virt.addr, walk.src.virt.addr, 903631c650SHerbert Xu walk.nbytes); 913631c650SHerbert Xu err = blkcipher_walk_done(desc, &walk, 0); 923631c650SHerbert Xu } 933631c650SHerbert Xu 943631c650SHerbert Xu return err; 953631c650SHerbert Xu } 963631c650SHerbert Xu 97d35d2454SHerbert Xu static struct shash_alg digest_null = { 98d35d2454SHerbert Xu .digestsize = NULL_DIGEST_SIZE, 99d35d2454SHerbert Xu .setkey = null_hash_setkey, 100d35d2454SHerbert Xu .init = null_init, 101d35d2454SHerbert Xu .update = null_update, 102d35d2454SHerbert Xu .finup = null_digest, 103d35d2454SHerbert Xu .digest = null_digest, 104d35d2454SHerbert Xu .final = null_final, 105d35d2454SHerbert Xu .base = { 1061da177e4SLinus Torvalds .cra_name = "digest_null", 107d35d2454SHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_SHASH, 1081da177e4SLinus Torvalds .cra_blocksize = NULL_BLOCK_SIZE, 1091da177e4SLinus Torvalds .cra_module = THIS_MODULE, 110d35d2454SHerbert Xu } 1111da177e4SLinus Torvalds }; 1121da177e4SLinus Torvalds 11370a03bffSJussi Kivilinna static struct crypto_alg null_algs[3] = { { 1141da177e4SLinus Torvalds .cra_name = "cipher_null", 1151da177e4SLinus Torvalds .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 1161da177e4SLinus Torvalds .cra_blocksize = NULL_BLOCK_SIZE, 1171da177e4SLinus Torvalds .cra_ctxsize = 0, 1181da177e4SLinus Torvalds .cra_module = THIS_MODULE, 1191da177e4SLinus Torvalds .cra_u = { .cipher = { 1201da177e4SLinus Torvalds .cia_min_keysize = NULL_KEY_SIZE, 1211da177e4SLinus Torvalds .cia_max_keysize = NULL_KEY_SIZE, 1221da177e4SLinus Torvalds .cia_setkey = null_setkey, 123d0856009SPatrick McHardy .cia_encrypt = null_crypt, 124d0856009SPatrick McHardy .cia_decrypt = null_crypt } } 12570a03bffSJussi Kivilinna }, { 1263631c650SHerbert Xu .cra_name = "ecb(cipher_null)", 1273631c650SHerbert Xu .cra_driver_name = "ecb-cipher_null", 1283631c650SHerbert Xu .cra_priority = 100, 1293631c650SHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 1303631c650SHerbert Xu .cra_blocksize = NULL_BLOCK_SIZE, 1313631c650SHerbert Xu .cra_type = &crypto_blkcipher_type, 1323631c650SHerbert Xu .cra_ctxsize = 0, 1333631c650SHerbert Xu .cra_module = THIS_MODULE, 1343631c650SHerbert Xu .cra_u = { .blkcipher = { 1353631c650SHerbert Xu .min_keysize = NULL_KEY_SIZE, 1363631c650SHerbert Xu .max_keysize = NULL_KEY_SIZE, 1373631c650SHerbert Xu .ivsize = NULL_IV_SIZE, 1383631c650SHerbert Xu .setkey = null_setkey, 1393631c650SHerbert Xu .encrypt = skcipher_null_crypt, 1403631c650SHerbert Xu .decrypt = skcipher_null_crypt } } 14170a03bffSJussi Kivilinna }, { 14270a03bffSJussi Kivilinna .cra_name = "compress_null", 14370a03bffSJussi Kivilinna .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 14470a03bffSJussi Kivilinna .cra_blocksize = NULL_BLOCK_SIZE, 14570a03bffSJussi Kivilinna .cra_ctxsize = 0, 14670a03bffSJussi Kivilinna .cra_module = THIS_MODULE, 14770a03bffSJussi Kivilinna .cra_u = { .compress = { 14870a03bffSJussi Kivilinna .coa_compress = null_compress, 14970a03bffSJussi Kivilinna .coa_decompress = null_compress } } 15070a03bffSJussi Kivilinna } }; 1513631c650SHerbert Xu 1525d26a105SKees Cook MODULE_ALIAS_CRYPTO("compress_null"); 1535d26a105SKees Cook MODULE_ALIAS_CRYPTO("digest_null"); 1545d26a105SKees Cook MODULE_ALIAS_CRYPTO("cipher_null"); 1551da177e4SLinus Torvalds 15633023463SHerbert Xu struct crypto_blkcipher *crypto_get_default_null_skcipher(void) 15733023463SHerbert Xu { 15833023463SHerbert Xu struct crypto_blkcipher *tfm; 15933023463SHerbert Xu 16033023463SHerbert Xu mutex_lock(&crypto_default_null_skcipher_lock); 16133023463SHerbert Xu tfm = crypto_default_null_skcipher; 16233023463SHerbert Xu 16333023463SHerbert Xu if (!tfm) { 16433023463SHerbert Xu tfm = crypto_alloc_blkcipher("ecb(cipher_null)", 0, 0); 16533023463SHerbert Xu if (IS_ERR(tfm)) 16633023463SHerbert Xu goto unlock; 16733023463SHerbert Xu 16833023463SHerbert Xu crypto_default_null_skcipher = tfm; 16933023463SHerbert Xu } 17033023463SHerbert Xu 17133023463SHerbert Xu crypto_default_null_skcipher_refcnt++; 17233023463SHerbert Xu 17333023463SHerbert Xu unlock: 17433023463SHerbert Xu mutex_unlock(&crypto_default_null_skcipher_lock); 17533023463SHerbert Xu 17633023463SHerbert Xu return tfm; 17733023463SHerbert Xu } 17833023463SHerbert Xu EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher); 17933023463SHerbert Xu 18033023463SHerbert Xu void crypto_put_default_null_skcipher(void) 18133023463SHerbert Xu { 18233023463SHerbert Xu mutex_lock(&crypto_default_null_skcipher_lock); 18333023463SHerbert Xu if (!--crypto_default_null_skcipher_refcnt) { 18433023463SHerbert Xu crypto_free_blkcipher(crypto_default_null_skcipher); 18533023463SHerbert Xu crypto_default_null_skcipher = NULL; 18633023463SHerbert Xu } 18733023463SHerbert Xu mutex_unlock(&crypto_default_null_skcipher_lock); 18833023463SHerbert Xu } 18933023463SHerbert Xu EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher); 19033023463SHerbert Xu 1913af5b90bSKamalesh Babulal static int __init crypto_null_mod_init(void) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds int ret = 0; 1941da177e4SLinus Torvalds 19570a03bffSJussi Kivilinna ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs)); 1961da177e4SLinus Torvalds if (ret < 0) 1971da177e4SLinus Torvalds goto out; 1981da177e4SLinus Torvalds 199d35d2454SHerbert Xu ret = crypto_register_shash(&digest_null); 2003631c650SHerbert Xu if (ret < 0) 20170a03bffSJussi Kivilinna goto out_unregister_algs; 2021da177e4SLinus Torvalds 20370a03bffSJussi Kivilinna return 0; 2041da177e4SLinus Torvalds 20570a03bffSJussi Kivilinna out_unregister_algs: 20670a03bffSJussi Kivilinna crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs)); 2071da177e4SLinus Torvalds out: 2081da177e4SLinus Torvalds return ret; 2091da177e4SLinus Torvalds } 2101da177e4SLinus Torvalds 2113af5b90bSKamalesh Babulal static void __exit crypto_null_mod_fini(void) 2121da177e4SLinus Torvalds { 213d35d2454SHerbert Xu crypto_unregister_shash(&digest_null); 21470a03bffSJussi Kivilinna crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs)); 2151da177e4SLinus Torvalds } 2161da177e4SLinus Torvalds 2173af5b90bSKamalesh Babulal module_init(crypto_null_mod_init); 2183af5b90bSKamalesh Babulal module_exit(crypto_null_mod_fini); 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 2211da177e4SLinus Torvalds MODULE_DESCRIPTION("Null Cryptographic Algorithms"); 222