xref: /netbsd-src/sys/crypto/chacha/arch/arm/chacha_neon_impl.c (revision 4a48ef14f28a7f1bb1ffa26e1c785fb04325410e)
1*4a48ef14Sjmcneill /*	$NetBSD: chacha_neon_impl.c,v 1.2 2020/10/10 08:24:10 jmcneill Exp $	*/
211faae69Sriastradh 
311faae69Sriastradh /*-
411faae69Sriastradh  * Copyright (c) 2020 The NetBSD Foundation, Inc.
511faae69Sriastradh  * All rights reserved.
611faae69Sriastradh  *
711faae69Sriastradh  * Redistribution and use in source and binary forms, with or without
811faae69Sriastradh  * modification, are permitted provided that the following conditions
911faae69Sriastradh  * are met:
1011faae69Sriastradh  * 1. Redistributions of source code must retain the above copyright
1111faae69Sriastradh  *    notice, this list of conditions and the following disclaimer.
1211faae69Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
1311faae69Sriastradh  *    notice, this list of conditions and the following disclaimer in the
1411faae69Sriastradh  *    documentation and/or other materials provided with the distribution.
1511faae69Sriastradh  *
1611faae69Sriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1711faae69Sriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1811faae69Sriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1911faae69Sriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2011faae69Sriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2111faae69Sriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2211faae69Sriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2311faae69Sriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2411faae69Sriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2511faae69Sriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2611faae69Sriastradh  * POSSIBILITY OF SUCH DAMAGE.
2711faae69Sriastradh  */
2811faae69Sriastradh 
2911faae69Sriastradh #include <sys/cdefs.h>
30*4a48ef14Sjmcneill __KERNEL_RCSID(1, "$NetBSD: chacha_neon_impl.c,v 1.2 2020/10/10 08:24:10 jmcneill Exp $");
3111faae69Sriastradh 
3211faae69Sriastradh #include "chacha_neon.h"
3311faae69Sriastradh 
3411faae69Sriastradh #ifdef __aarch64__
3511faae69Sriastradh #include <aarch64/armreg.h>
3611faae69Sriastradh #endif
3711faae69Sriastradh 
3811faae69Sriastradh #ifdef _KERNEL
3911faae69Sriastradh #include <sys/proc.h>
4011faae69Sriastradh #ifndef __aarch64__
4111faae69Sriastradh #include <arm/locore.h>
4211faae69Sriastradh #endif
4311faae69Sriastradh #include <arm/fpu.h>
4411faae69Sriastradh #else
4511faae69Sriastradh #include <sys/sysctl.h>
4611faae69Sriastradh #include <stddef.h>
4711faae69Sriastradh #define	fpu_kern_enter()	((void)0)
4811faae69Sriastradh #define	fpu_kern_leave()	((void)0)
4911faae69Sriastradh #endif
5011faae69Sriastradh 
5111faae69Sriastradh static void
chacha_core_neon_impl(uint8_t out[restrict static64],const uint8_t in[static16],const uint8_t k[static32],const uint8_t c[static16],unsigned nr)5211faae69Sriastradh chacha_core_neon_impl(uint8_t out[restrict static 64],
5311faae69Sriastradh     const uint8_t in[static 16],
5411faae69Sriastradh     const uint8_t k[static 32],
5511faae69Sriastradh     const uint8_t c[static 16],
5611faae69Sriastradh     unsigned nr)
5711faae69Sriastradh {
5811faae69Sriastradh 
5911faae69Sriastradh 	fpu_kern_enter();
6011faae69Sriastradh 	chacha_core_neon(out, in, k, c, nr);
6111faae69Sriastradh 	fpu_kern_leave();
6211faae69Sriastradh }
6311faae69Sriastradh 
6411faae69Sriastradh static void
hchacha_neon_impl(uint8_t out[restrict static32],const uint8_t in[static16],const uint8_t k[static32],const uint8_t c[static16],unsigned nr)6511faae69Sriastradh hchacha_neon_impl(uint8_t out[restrict static 32],
6611faae69Sriastradh     const uint8_t in[static 16],
6711faae69Sriastradh     const uint8_t k[static 32],
6811faae69Sriastradh     const uint8_t c[static 16],
6911faae69Sriastradh     unsigned nr)
7011faae69Sriastradh {
7111faae69Sriastradh 
7211faae69Sriastradh 	fpu_kern_enter();
7311faae69Sriastradh 	hchacha_neon(out, in, k, c, nr);
7411faae69Sriastradh 	fpu_kern_leave();
7511faae69Sriastradh }
7611faae69Sriastradh 
7711faae69Sriastradh static void
chacha_stream_neon_impl(uint8_t * restrict s,size_t nbytes,uint32_t blkno,const uint8_t nonce[static12],const uint8_t key[static32],unsigned nr)7811faae69Sriastradh chacha_stream_neon_impl(uint8_t *restrict s, size_t nbytes, uint32_t blkno,
7911faae69Sriastradh     const uint8_t nonce[static 12],
8011faae69Sriastradh     const uint8_t key[static 32],
8111faae69Sriastradh     unsigned nr)
8211faae69Sriastradh {
8311faae69Sriastradh 
8411faae69Sriastradh 	fpu_kern_enter();
8511faae69Sriastradh 	chacha_stream_neon(s, nbytes, blkno, nonce, key, nr);
8611faae69Sriastradh 	fpu_kern_leave();
8711faae69Sriastradh }
8811faae69Sriastradh 
8911faae69Sriastradh static void
chacha_stream_xor_neon_impl(uint8_t * c,const uint8_t * p,size_t nbytes,uint32_t blkno,const uint8_t nonce[static12],const uint8_t key[static32],unsigned nr)9011faae69Sriastradh chacha_stream_xor_neon_impl(uint8_t *c, const uint8_t *p, size_t nbytes,
9111faae69Sriastradh     uint32_t blkno,
9211faae69Sriastradh     const uint8_t nonce[static 12],
9311faae69Sriastradh     const uint8_t key[static 32],
9411faae69Sriastradh     unsigned nr)
9511faae69Sriastradh {
9611faae69Sriastradh 
9711faae69Sriastradh 	fpu_kern_enter();
9811faae69Sriastradh 	chacha_stream_xor_neon(c, p, nbytes, blkno, nonce, key, nr);
9911faae69Sriastradh 	fpu_kern_leave();
10011faae69Sriastradh }
10111faae69Sriastradh 
10211faae69Sriastradh static void
xchacha_stream_neon_impl(uint8_t * restrict s,size_t nbytes,uint32_t blkno,const uint8_t nonce[static24],const uint8_t key[static32],unsigned nr)10311faae69Sriastradh xchacha_stream_neon_impl(uint8_t *restrict s, size_t nbytes, uint32_t blkno,
10411faae69Sriastradh     const uint8_t nonce[static 24],
10511faae69Sriastradh     const uint8_t key[static 32],
10611faae69Sriastradh     unsigned nr)
10711faae69Sriastradh {
10811faae69Sriastradh 
10911faae69Sriastradh 	fpu_kern_enter();
11011faae69Sriastradh 	xchacha_stream_neon(s, nbytes, blkno, nonce, key, nr);
11111faae69Sriastradh 	fpu_kern_leave();
11211faae69Sriastradh }
11311faae69Sriastradh 
11411faae69Sriastradh static void
xchacha_stream_xor_neon_impl(uint8_t * c,const uint8_t * p,size_t nbytes,uint32_t blkno,const uint8_t nonce[static24],const uint8_t key[static32],unsigned nr)11511faae69Sriastradh xchacha_stream_xor_neon_impl(uint8_t *c, const uint8_t *p, size_t nbytes,
11611faae69Sriastradh     uint32_t blkno,
11711faae69Sriastradh     const uint8_t nonce[static 24],
11811faae69Sriastradh     const uint8_t key[static 32],
11911faae69Sriastradh     unsigned nr)
12011faae69Sriastradh {
12111faae69Sriastradh 
12211faae69Sriastradh 	fpu_kern_enter();
12311faae69Sriastradh 	xchacha_stream_xor_neon(c, p, nbytes, blkno, nonce, key, nr);
12411faae69Sriastradh 	fpu_kern_leave();
12511faae69Sriastradh }
12611faae69Sriastradh 
12711faae69Sriastradh static int
chacha_probe_neon(void)12811faae69Sriastradh chacha_probe_neon(void)
12911faae69Sriastradh {
13011faae69Sriastradh #ifdef __aarch64__
13111faae69Sriastradh 	struct aarch64_sysctl_cpu_id *id;
13211faae69Sriastradh #endif
13311faae69Sriastradh 	int result = 0;
13411faae69Sriastradh 
13511faae69Sriastradh 	/* Verify that the CPU supports NEON.  */
13611faae69Sriastradh #ifdef __aarch64__
13711faae69Sriastradh #ifdef _KERNEL
13811faae69Sriastradh 	id = &curcpu()->ci_id;
13911faae69Sriastradh #else
14011faae69Sriastradh 	struct aarch64_sysctl_cpu_id ids;
14111faae69Sriastradh 	size_t idlen;
14211faae69Sriastradh 	id = &ids;
14311faae69Sriastradh 	idlen = sizeof ids;
14411faae69Sriastradh 	if (sysctlbyname("machdep.cpu0.cpu_id", id, &idlen, NULL, 0))
14511faae69Sriastradh 		return -1;
14611faae69Sriastradh 	if (idlen != sizeof ids)
14711faae69Sriastradh 		return -1;
14811faae69Sriastradh #endif
14911faae69Sriastradh 	switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
150*4a48ef14Sjmcneill 	case ID_AA64PFR0_EL1_ADV_SIMD_NONE:
15111faae69Sriastradh 		return -1;
152*4a48ef14Sjmcneill 	default:
153*4a48ef14Sjmcneill 		break;
15411faae69Sriastradh 	}
15511faae69Sriastradh #else
15611faae69Sriastradh #ifdef _KERNEL
15711faae69Sriastradh 	if (!cpu_neon_present)
15811faae69Sriastradh 		return -1;
15911faae69Sriastradh #else
16011faae69Sriastradh 	int neon;
16111faae69Sriastradh 	size_t neonlen = sizeof neon;
16211faae69Sriastradh 	if (sysctlbyname("machdep.neon_present", &neon, &neonlen, NULL, 0))
16311faae69Sriastradh 		return -1;
16411faae69Sriastradh 	if (!neon)
16511faae69Sriastradh 		return -1;
16611faae69Sriastradh #endif
16711faae69Sriastradh #endif
16811faae69Sriastradh 
16911faae69Sriastradh 	return result;
17011faae69Sriastradh }
17111faae69Sriastradh 
17211faae69Sriastradh const struct chacha_impl chacha_neon_impl = {
17311faae69Sriastradh 	.ci_name = "ARM NEON ChaCha",
17411faae69Sriastradh 	.ci_probe = chacha_probe_neon,
17511faae69Sriastradh 	.ci_chacha_core = chacha_core_neon_impl,
17611faae69Sriastradh 	.ci_hchacha = hchacha_neon_impl,
17711faae69Sriastradh 	.ci_chacha_stream = chacha_stream_neon_impl,
17811faae69Sriastradh 	.ci_chacha_stream_xor = chacha_stream_xor_neon_impl,
17911faae69Sriastradh 	.ci_xchacha_stream = xchacha_stream_neon_impl,
18011faae69Sriastradh 	.ci_xchacha_stream_xor = xchacha_stream_xor_neon_impl,
18111faae69Sriastradh };
182