1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * ChaCha stream cipher (s390 optimized) 4 * 5 * Copyright IBM Corp. 2021 6 */ 7 8 #define KMSG_COMPONENT "chacha_s390" 9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 11 #include <crypto/chacha.h> 12 #include <linux/cpufeature.h> 13 #include <linux/export.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/sizes.h> 17 #include <asm/fpu.h> 18 #include "chacha-s390.h" 19 20 void hchacha_block_arch(const struct chacha_state *state, 21 u32 out[HCHACHA_OUT_WORDS], int nrounds) 22 { 23 /* TODO: implement hchacha_block_arch() in assembly */ 24 hchacha_block_generic(state, out, nrounds); 25 } 26 EXPORT_SYMBOL(hchacha_block_arch); 27 28 void chacha_crypt_arch(struct chacha_state *state, u8 *dst, const u8 *src, 29 unsigned int bytes, int nrounds) 30 { 31 /* s390 chacha20 implementation has 20 rounds hard-coded, 32 * it cannot handle a block of data or less, but otherwise 33 * it can handle data of arbitrary size 34 */ 35 if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !cpu_has_vx()) { 36 chacha_crypt_generic(state, dst, src, bytes, nrounds); 37 } else { 38 DECLARE_KERNEL_FPU_ONSTACK32(vxstate); 39 40 kernel_fpu_begin(&vxstate, KERNEL_VXR); 41 chacha20_vx(dst, src, bytes, &state->x[4], &state->x[12]); 42 kernel_fpu_end(&vxstate, KERNEL_VXR); 43 44 state->x[12] += round_up(bytes, CHACHA_BLOCK_SIZE) / 45 CHACHA_BLOCK_SIZE; 46 } 47 } 48 EXPORT_SYMBOL(chacha_crypt_arch); 49 50 bool chacha_is_arch_optimized(void) 51 { 52 return cpu_has_vx(); 53 } 54 EXPORT_SYMBOL(chacha_is_arch_optimized); 55 56 MODULE_DESCRIPTION("ChaCha stream cipher (s390 optimized)"); 57 MODULE_LICENSE("GPL v2"); 58