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 20*d35d2454SHerbert Xu #include <crypto/internal/hash.h> 213631c650SHerbert Xu #include <crypto/internal/skcipher.h> 221da177e4SLinus Torvalds #include <linux/init.h> 231da177e4SLinus Torvalds #include <linux/module.h> 241da177e4SLinus Torvalds #include <linux/mm.h> 25d0856009SPatrick McHardy #include <linux/string.h> 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #define NULL_KEY_SIZE 0 281da177e4SLinus Torvalds #define NULL_BLOCK_SIZE 1 291da177e4SLinus Torvalds #define NULL_DIGEST_SIZE 0 303631c650SHerbert Xu #define NULL_IV_SIZE 0 311da177e4SLinus Torvalds 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 42*d35d2454SHerbert Xu static int null_init(struct shash_desc *desc) 43*d35d2454SHerbert Xu { 44*d35d2454SHerbert Xu return 0; 45*d35d2454SHerbert Xu } 461da177e4SLinus Torvalds 47*d35d2454SHerbert Xu static int null_update(struct shash_desc *desc, const u8 *data, 486c2bb98bSHerbert Xu unsigned int len) 49*d35d2454SHerbert Xu { 50*d35d2454SHerbert Xu return 0; 51*d35d2454SHerbert Xu } 521da177e4SLinus Torvalds 53*d35d2454SHerbert Xu static int null_final(struct shash_desc *desc, u8 *out) 54*d35d2454SHerbert Xu { 55*d35d2454SHerbert Xu return 0; 56*d35d2454SHerbert Xu } 57*d35d2454SHerbert Xu 58*d35d2454SHerbert Xu static int null_digest(struct shash_desc *desc, const u8 *data, 59*d35d2454SHerbert Xu unsigned int len, u8 *out) 60*d35d2454SHerbert Xu { 61*d35d2454SHerbert Xu return 0; 62*d35d2454SHerbert Xu } 63*d35d2454SHerbert Xu 64*d35d2454SHerbert Xu static int null_hash_setkey(struct crypto_shash *tfm, const u8 *key, 65*d35d2454SHerbert Xu unsigned int keylen) 66*d35d2454SHerbert 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 971da177e4SLinus Torvalds static struct crypto_alg compress_null = { 981da177e4SLinus Torvalds .cra_name = "compress_null", 991da177e4SLinus Torvalds .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 1001da177e4SLinus Torvalds .cra_blocksize = NULL_BLOCK_SIZE, 1011da177e4SLinus Torvalds .cra_ctxsize = 0, 1021da177e4SLinus Torvalds .cra_module = THIS_MODULE, 1031da177e4SLinus Torvalds .cra_list = LIST_HEAD_INIT(compress_null.cra_list), 1041da177e4SLinus Torvalds .cra_u = { .compress = { 1051da177e4SLinus Torvalds .coa_compress = null_compress, 106d0856009SPatrick McHardy .coa_decompress = null_compress } } 1071da177e4SLinus Torvalds }; 1081da177e4SLinus Torvalds 109*d35d2454SHerbert Xu static struct shash_alg digest_null = { 110*d35d2454SHerbert Xu .digestsize = NULL_DIGEST_SIZE, 111*d35d2454SHerbert Xu .setkey = null_hash_setkey, 112*d35d2454SHerbert Xu .init = null_init, 113*d35d2454SHerbert Xu .update = null_update, 114*d35d2454SHerbert Xu .finup = null_digest, 115*d35d2454SHerbert Xu .digest = null_digest, 116*d35d2454SHerbert Xu .final = null_final, 117*d35d2454SHerbert Xu .base = { 1181da177e4SLinus Torvalds .cra_name = "digest_null", 119*d35d2454SHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_SHASH, 1201da177e4SLinus Torvalds .cra_blocksize = NULL_BLOCK_SIZE, 1211da177e4SLinus Torvalds .cra_module = THIS_MODULE, 122*d35d2454SHerbert Xu } 1231da177e4SLinus Torvalds }; 1241da177e4SLinus Torvalds 1251da177e4SLinus Torvalds static struct crypto_alg cipher_null = { 1261da177e4SLinus Torvalds .cra_name = "cipher_null", 1271da177e4SLinus Torvalds .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 1281da177e4SLinus Torvalds .cra_blocksize = NULL_BLOCK_SIZE, 1291da177e4SLinus Torvalds .cra_ctxsize = 0, 1301da177e4SLinus Torvalds .cra_module = THIS_MODULE, 1311da177e4SLinus Torvalds .cra_list = LIST_HEAD_INIT(cipher_null.cra_list), 1321da177e4SLinus Torvalds .cra_u = { .cipher = { 1331da177e4SLinus Torvalds .cia_min_keysize = NULL_KEY_SIZE, 1341da177e4SLinus Torvalds .cia_max_keysize = NULL_KEY_SIZE, 1351da177e4SLinus Torvalds .cia_setkey = null_setkey, 136d0856009SPatrick McHardy .cia_encrypt = null_crypt, 137d0856009SPatrick McHardy .cia_decrypt = null_crypt } } 1381da177e4SLinus Torvalds }; 1391da177e4SLinus Torvalds 1403631c650SHerbert Xu static struct crypto_alg skcipher_null = { 1413631c650SHerbert Xu .cra_name = "ecb(cipher_null)", 1423631c650SHerbert Xu .cra_driver_name = "ecb-cipher_null", 1433631c650SHerbert Xu .cra_priority = 100, 1443631c650SHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 1453631c650SHerbert Xu .cra_blocksize = NULL_BLOCK_SIZE, 1463631c650SHerbert Xu .cra_type = &crypto_blkcipher_type, 1473631c650SHerbert Xu .cra_ctxsize = 0, 1483631c650SHerbert Xu .cra_module = THIS_MODULE, 1493631c650SHerbert Xu .cra_list = LIST_HEAD_INIT(skcipher_null.cra_list), 1503631c650SHerbert Xu .cra_u = { .blkcipher = { 1513631c650SHerbert Xu .min_keysize = NULL_KEY_SIZE, 1523631c650SHerbert Xu .max_keysize = NULL_KEY_SIZE, 1533631c650SHerbert Xu .ivsize = NULL_IV_SIZE, 1543631c650SHerbert Xu .setkey = null_setkey, 1553631c650SHerbert Xu .encrypt = skcipher_null_crypt, 1563631c650SHerbert Xu .decrypt = skcipher_null_crypt } } 1573631c650SHerbert Xu }; 1583631c650SHerbert Xu 1591da177e4SLinus Torvalds MODULE_ALIAS("compress_null"); 1601da177e4SLinus Torvalds MODULE_ALIAS("digest_null"); 1611da177e4SLinus Torvalds MODULE_ALIAS("cipher_null"); 1621da177e4SLinus Torvalds 1633af5b90bSKamalesh Babulal static int __init crypto_null_mod_init(void) 1641da177e4SLinus Torvalds { 1651da177e4SLinus Torvalds int ret = 0; 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds ret = crypto_register_alg(&cipher_null); 1681da177e4SLinus Torvalds if (ret < 0) 1691da177e4SLinus Torvalds goto out; 1701da177e4SLinus Torvalds 1713631c650SHerbert Xu ret = crypto_register_alg(&skcipher_null); 1723631c650SHerbert Xu if (ret < 0) 1733631c650SHerbert Xu goto out_unregister_cipher; 1743631c650SHerbert Xu 175*d35d2454SHerbert Xu ret = crypto_register_shash(&digest_null); 1763631c650SHerbert Xu if (ret < 0) 1773631c650SHerbert Xu goto out_unregister_skcipher; 1781da177e4SLinus Torvalds 1791da177e4SLinus Torvalds ret = crypto_register_alg(&compress_null); 1803631c650SHerbert Xu if (ret < 0) 1813631c650SHerbert Xu goto out_unregister_digest; 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds out: 1841da177e4SLinus Torvalds return ret; 1853631c650SHerbert Xu 1863631c650SHerbert Xu out_unregister_digest: 187*d35d2454SHerbert Xu crypto_unregister_shash(&digest_null); 1883631c650SHerbert Xu out_unregister_skcipher: 1893631c650SHerbert Xu crypto_unregister_alg(&skcipher_null); 1903631c650SHerbert Xu out_unregister_cipher: 1913631c650SHerbert Xu crypto_unregister_alg(&cipher_null); 1923631c650SHerbert Xu goto out; 1931da177e4SLinus Torvalds } 1941da177e4SLinus Torvalds 1953af5b90bSKamalesh Babulal static void __exit crypto_null_mod_fini(void) 1961da177e4SLinus Torvalds { 1971da177e4SLinus Torvalds crypto_unregister_alg(&compress_null); 198*d35d2454SHerbert Xu crypto_unregister_shash(&digest_null); 1993631c650SHerbert Xu crypto_unregister_alg(&skcipher_null); 2001da177e4SLinus Torvalds crypto_unregister_alg(&cipher_null); 2011da177e4SLinus Torvalds } 2021da177e4SLinus Torvalds 2033af5b90bSKamalesh Babulal module_init(crypto_null_mod_init); 2043af5b90bSKamalesh Babulal module_exit(crypto_null_mod_fini); 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 2071da177e4SLinus Torvalds MODULE_DESCRIPTION("Null Cryptographic Algorithms"); 208