brintos

brintos / linux-shallow public Read only

0
0
Text · 3.9 KiB · ba7fcb4 Raw
140 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * ChaCha and XChaCha stream ciphers, including ChaCha20 (RFC7539)4 *5 * Copyright (C) 2015 Martin Willi6 * Copyright (C) 2018 Google LLC7 */8 9#include <linux/unaligned.h>10#include <crypto/algapi.h>11#include <crypto/internal/chacha.h>12#include <crypto/internal/skcipher.h>13#include <linux/module.h>14 15static int chacha_stream_xor(struct skcipher_request *req,16			     const struct chacha_ctx *ctx, const u8 *iv)17{18	struct skcipher_walk walk;19	u32 state[16];20	int err;21 22	err = skcipher_walk_virt(&walk, req, false);23 24	chacha_init_generic(state, ctx->key, iv);25 26	while (walk.nbytes > 0) {27		unsigned int nbytes = walk.nbytes;28 29		if (nbytes < walk.total)30			nbytes = round_down(nbytes, CHACHA_BLOCK_SIZE);31 32		chacha_crypt_generic(state, walk.dst.virt.addr,33				     walk.src.virt.addr, nbytes, ctx->nrounds);34		err = skcipher_walk_done(&walk, walk.nbytes - nbytes);35	}36 37	return err;38}39 40static int crypto_chacha_crypt(struct skcipher_request *req)41{42	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);43	struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);44 45	return chacha_stream_xor(req, ctx, req->iv);46}47 48static int crypto_xchacha_crypt(struct skcipher_request *req)49{50	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);51	struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);52	struct chacha_ctx subctx;53	u32 state[16];54	u8 real_iv[16];55 56	/* Compute the subkey given the original key and first 128 nonce bits */57	chacha_init_generic(state, ctx->key, req->iv);58	hchacha_block_generic(state, subctx.key, ctx->nrounds);59	subctx.nrounds = ctx->nrounds;60 61	/* Build the real IV */62	memcpy(&real_iv[0], req->iv + 24, 8); /* stream position */63	memcpy(&real_iv[8], req->iv + 16, 8); /* remaining 64 nonce bits */64 65	/* Generate the stream and XOR it with the data */66	return chacha_stream_xor(req, &subctx, real_iv);67}68 69static struct skcipher_alg algs[] = {70	{71		.base.cra_name		= "chacha20",72		.base.cra_driver_name	= "chacha20-generic",73		.base.cra_priority	= 100,74		.base.cra_blocksize	= 1,75		.base.cra_ctxsize	= sizeof(struct chacha_ctx),76		.base.cra_module	= THIS_MODULE,77 78		.min_keysize		= CHACHA_KEY_SIZE,79		.max_keysize		= CHACHA_KEY_SIZE,80		.ivsize			= CHACHA_IV_SIZE,81		.chunksize		= CHACHA_BLOCK_SIZE,82		.setkey			= chacha20_setkey,83		.encrypt		= crypto_chacha_crypt,84		.decrypt		= crypto_chacha_crypt,85	}, {86		.base.cra_name		= "xchacha20",87		.base.cra_driver_name	= "xchacha20-generic",88		.base.cra_priority	= 100,89		.base.cra_blocksize	= 1,90		.base.cra_ctxsize	= sizeof(struct chacha_ctx),91		.base.cra_module	= THIS_MODULE,92 93		.min_keysize		= CHACHA_KEY_SIZE,94		.max_keysize		= CHACHA_KEY_SIZE,95		.ivsize			= XCHACHA_IV_SIZE,96		.chunksize		= CHACHA_BLOCK_SIZE,97		.setkey			= chacha20_setkey,98		.encrypt		= crypto_xchacha_crypt,99		.decrypt		= crypto_xchacha_crypt,100	}, {101		.base.cra_name		= "xchacha12",102		.base.cra_driver_name	= "xchacha12-generic",103		.base.cra_priority	= 100,104		.base.cra_blocksize	= 1,105		.base.cra_ctxsize	= sizeof(struct chacha_ctx),106		.base.cra_module	= THIS_MODULE,107 108		.min_keysize		= CHACHA_KEY_SIZE,109		.max_keysize		= CHACHA_KEY_SIZE,110		.ivsize			= XCHACHA_IV_SIZE,111		.chunksize		= CHACHA_BLOCK_SIZE,112		.setkey			= chacha12_setkey,113		.encrypt		= crypto_xchacha_crypt,114		.decrypt		= crypto_xchacha_crypt,115	}116};117 118static int __init chacha_generic_mod_init(void)119{120	return crypto_register_skciphers(algs, ARRAY_SIZE(algs));121}122 123static void __exit chacha_generic_mod_fini(void)124{125	crypto_unregister_skciphers(algs, ARRAY_SIZE(algs));126}127 128subsys_initcall(chacha_generic_mod_init);129module_exit(chacha_generic_mod_fini);130 131MODULE_LICENSE("GPL");132MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");133MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (generic)");134MODULE_ALIAS_CRYPTO("chacha20");135MODULE_ALIAS_CRYPTO("chacha20-generic");136MODULE_ALIAS_CRYPTO("xchacha20");137MODULE_ALIAS_CRYPTO("xchacha20-generic");138MODULE_ALIAS_CRYPTO("xchacha12");139MODULE_ALIAS_CRYPTO("xchacha12-generic");140