162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * The ChaCha stream cipher (RFC7539) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015 Martin Willi 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/kernel.h> 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <crypto/algapi.h> // for crypto_xor_cpy 1362306a36Sopenharmony_ci#include <crypto/chacha.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_civoid chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src, 1662306a36Sopenharmony_ci unsigned int bytes, int nrounds) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci /* aligned to potentially speed up crypto_xor() */ 1962306a36Sopenharmony_ci u8 stream[CHACHA_BLOCK_SIZE] __aligned(sizeof(long)); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci while (bytes >= CHACHA_BLOCK_SIZE) { 2262306a36Sopenharmony_ci chacha_block_generic(state, stream, nrounds); 2362306a36Sopenharmony_ci crypto_xor_cpy(dst, src, stream, CHACHA_BLOCK_SIZE); 2462306a36Sopenharmony_ci bytes -= CHACHA_BLOCK_SIZE; 2562306a36Sopenharmony_ci dst += CHACHA_BLOCK_SIZE; 2662306a36Sopenharmony_ci src += CHACHA_BLOCK_SIZE; 2762306a36Sopenharmony_ci } 2862306a36Sopenharmony_ci if (bytes) { 2962306a36Sopenharmony_ci chacha_block_generic(state, stream, nrounds); 3062306a36Sopenharmony_ci crypto_xor_cpy(dst, src, stream, bytes); 3162306a36Sopenharmony_ci } 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ciEXPORT_SYMBOL(chacha_crypt_generic); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 36