15fb8ef25SArd Biesheuvel // SPDX-License-Identifier: GPL-2.0-or-later
25fb8ef25SArd Biesheuvel /*
35fb8ef25SArd Biesheuvel * The ChaCha stream cipher (RFC7539)
45fb8ef25SArd Biesheuvel *
55fb8ef25SArd Biesheuvel * Copyright (C) 2015 Martin Willi
65fb8ef25SArd Biesheuvel */
75fb8ef25SArd Biesheuvel
85fb8ef25SArd Biesheuvel #include <linux/kernel.h>
95fb8ef25SArd Biesheuvel #include <linux/export.h>
105fb8ef25SArd Biesheuvel #include <linux/module.h>
115fb8ef25SArd Biesheuvel
125fb8ef25SArd Biesheuvel #include <crypto/algapi.h> // for crypto_xor_cpy
135fb8ef25SArd Biesheuvel #include <crypto/chacha.h>
145fb8ef25SArd Biesheuvel
chacha_crypt_generic(u32 * state,u8 * dst,const u8 * src,unsigned int bytes,int nrounds)155fb8ef25SArd Biesheuvel void chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src,
165fb8ef25SArd Biesheuvel unsigned int bytes, int nrounds)
175fb8ef25SArd Biesheuvel {
185fb8ef25SArd Biesheuvel /* aligned to potentially speed up crypto_xor() */
195fb8ef25SArd Biesheuvel u8 stream[CHACHA_BLOCK_SIZE] __aligned(sizeof(long));
205fb8ef25SArd Biesheuvel
215fb8ef25SArd Biesheuvel while (bytes >= CHACHA_BLOCK_SIZE) {
225fb8ef25SArd Biesheuvel chacha_block_generic(state, stream, nrounds);
235fb8ef25SArd Biesheuvel crypto_xor_cpy(dst, src, stream, CHACHA_BLOCK_SIZE);
245fb8ef25SArd Biesheuvel bytes -= CHACHA_BLOCK_SIZE;
255fb8ef25SArd Biesheuvel dst += CHACHA_BLOCK_SIZE;
265fb8ef25SArd Biesheuvel src += CHACHA_BLOCK_SIZE;
275fb8ef25SArd Biesheuvel }
285fb8ef25SArd Biesheuvel if (bytes) {
295fb8ef25SArd Biesheuvel chacha_block_generic(state, stream, nrounds);
305fb8ef25SArd Biesheuvel crypto_xor_cpy(dst, src, stream, bytes);
315fb8ef25SArd Biesheuvel }
325fb8ef25SArd Biesheuvel }
335fb8ef25SArd Biesheuvel EXPORT_SYMBOL(chacha_crypt_generic);
345fb8ef25SArd Biesheuvel
35*645211dbSJeff Johnson MODULE_DESCRIPTION("ChaCha stream cipher (RFC7539)");
365fb8ef25SArd Biesheuvel MODULE_LICENSE("GPL");
37