1*5fb8ef25SArd Biesheuvel // SPDX-License-Identifier: GPL-2.0-or-later 2*5fb8ef25SArd Biesheuvel /* 3*5fb8ef25SArd Biesheuvel * The ChaCha stream cipher (RFC7539) 4*5fb8ef25SArd Biesheuvel * 5*5fb8ef25SArd Biesheuvel * Copyright (C) 2015 Martin Willi 6*5fb8ef25SArd Biesheuvel */ 7*5fb8ef25SArd Biesheuvel 8*5fb8ef25SArd Biesheuvel #include <linux/kernel.h> 9*5fb8ef25SArd Biesheuvel #include <linux/export.h> 10*5fb8ef25SArd Biesheuvel #include <linux/module.h> 11*5fb8ef25SArd Biesheuvel 12*5fb8ef25SArd Biesheuvel #include <crypto/algapi.h> // for crypto_xor_cpy 13*5fb8ef25SArd Biesheuvel #include <crypto/chacha.h> 14*5fb8ef25SArd Biesheuvel 15*5fb8ef25SArd Biesheuvel void chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src, 16*5fb8ef25SArd Biesheuvel unsigned int bytes, int nrounds) 17*5fb8ef25SArd Biesheuvel { 18*5fb8ef25SArd Biesheuvel /* aligned to potentially speed up crypto_xor() */ 19*5fb8ef25SArd Biesheuvel u8 stream[CHACHA_BLOCK_SIZE] __aligned(sizeof(long)); 20*5fb8ef25SArd Biesheuvel 21*5fb8ef25SArd Biesheuvel while (bytes >= CHACHA_BLOCK_SIZE) { 22*5fb8ef25SArd Biesheuvel chacha_block_generic(state, stream, nrounds); 23*5fb8ef25SArd Biesheuvel crypto_xor_cpy(dst, src, stream, CHACHA_BLOCK_SIZE); 24*5fb8ef25SArd Biesheuvel bytes -= CHACHA_BLOCK_SIZE; 25*5fb8ef25SArd Biesheuvel dst += CHACHA_BLOCK_SIZE; 26*5fb8ef25SArd Biesheuvel src += CHACHA_BLOCK_SIZE; 27*5fb8ef25SArd Biesheuvel } 28*5fb8ef25SArd Biesheuvel if (bytes) { 29*5fb8ef25SArd Biesheuvel chacha_block_generic(state, stream, nrounds); 30*5fb8ef25SArd Biesheuvel crypto_xor_cpy(dst, src, stream, bytes); 31*5fb8ef25SArd Biesheuvel } 32*5fb8ef25SArd Biesheuvel } 33*5fb8ef25SArd Biesheuvel EXPORT_SYMBOL(chacha_crypt_generic); 34*5fb8ef25SArd Biesheuvel 35*5fb8ef25SArd Biesheuvel MODULE_LICENSE("GPL"); 36