xref: /linux/lib/crypto/s390/chacha-glue.c (revision b4ada0618eed0fbd1b1630f73deb048c592b06a1)
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