18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * The ChaCha stream cipher (RFC7539) 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2015 Martin Willi 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include <linux/export.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <crypto/algapi.h> // for crypto_xor_cpy 138c2ecf20Sopenharmony_ci#include <crypto/chacha.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_civoid chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src, 168c2ecf20Sopenharmony_ci unsigned int bytes, int nrounds) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci /* aligned to potentially speed up crypto_xor() */ 198c2ecf20Sopenharmony_ci u8 stream[CHACHA_BLOCK_SIZE] __aligned(sizeof(long)); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci while (bytes >= CHACHA_BLOCK_SIZE) { 228c2ecf20Sopenharmony_ci chacha_block_generic(state, stream, nrounds); 238c2ecf20Sopenharmony_ci crypto_xor_cpy(dst, src, stream, CHACHA_BLOCK_SIZE); 248c2ecf20Sopenharmony_ci bytes -= CHACHA_BLOCK_SIZE; 258c2ecf20Sopenharmony_ci dst += CHACHA_BLOCK_SIZE; 268c2ecf20Sopenharmony_ci src += CHACHA_BLOCK_SIZE; 278c2ecf20Sopenharmony_ci } 288c2ecf20Sopenharmony_ci if (bytes) { 298c2ecf20Sopenharmony_ci chacha_block_generic(state, stream, nrounds); 308c2ecf20Sopenharmony_ci crypto_xor_cpy(dst, src, stream, bytes); 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ciEXPORT_SYMBOL(chacha_crypt_generic); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 36