xref: /netbsd-src/sys/crypto/aes/arch/arm/aes_neon_impl.c (revision 4a48ef14f28a7f1bb1ffa26e1c785fb04325410e)
1*4a48ef14Sjmcneill /*	$NetBSD: aes_neon_impl.c,v 1.5 2020/10/10 08:24:10 jmcneill Exp $	*/
20a776e17Sriastradh 
30a776e17Sriastradh /*-
40a776e17Sriastradh  * Copyright (c) 2020 The NetBSD Foundation, Inc.
50a776e17Sriastradh  * All rights reserved.
60a776e17Sriastradh  *
70a776e17Sriastradh  * Redistribution and use in source and binary forms, with or without
80a776e17Sriastradh  * modification, are permitted provided that the following conditions
90a776e17Sriastradh  * are met:
100a776e17Sriastradh  * 1. Redistributions of source code must retain the above copyright
110a776e17Sriastradh  *    notice, this list of conditions and the following disclaimer.
120a776e17Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
130a776e17Sriastradh  *    notice, this list of conditions and the following disclaimer in the
140a776e17Sriastradh  *    documentation and/or other materials provided with the distribution.
150a776e17Sriastradh  *
160a776e17Sriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
170a776e17Sriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
180a776e17Sriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
190a776e17Sriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
200a776e17Sriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
210a776e17Sriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
220a776e17Sriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
230a776e17Sriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
240a776e17Sriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
250a776e17Sriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
260a776e17Sriastradh  * POSSIBILITY OF SUCH DAMAGE.
270a776e17Sriastradh  */
280a776e17Sriastradh 
290a776e17Sriastradh #include <sys/cdefs.h>
30*4a48ef14Sjmcneill __KERNEL_RCSID(1, "$NetBSD: aes_neon_impl.c,v 1.5 2020/10/10 08:24:10 jmcneill Exp $");
310a776e17Sriastradh 
320a776e17Sriastradh #include <sys/types.h>
330a776e17Sriastradh #include <sys/proc.h>
340a776e17Sriastradh 
350a776e17Sriastradh #include <crypto/aes/aes.h>
36518b19bbSriastradh #include <crypto/aes/aes_impl.h>
370a776e17Sriastradh #include <crypto/aes/arch/arm/aes_neon.h>
380a776e17Sriastradh 
390a776e17Sriastradh #ifdef __aarch64__
400a776e17Sriastradh #include <aarch64/armreg.h>
41bd9707e0Sriastradh #endif
42bd9707e0Sriastradh 
43bd9707e0Sriastradh #ifdef _KERNEL
44bd9707e0Sriastradh #ifndef __aarch64__
450a776e17Sriastradh #include <arm/locore.h>
460a776e17Sriastradh #endif
47bd9707e0Sriastradh #include <arm/fpu.h>
48bd9707e0Sriastradh #else
49bd9707e0Sriastradh #include <sys/sysctl.h>
50bd9707e0Sriastradh #include <stddef.h>
51bd9707e0Sriastradh #define	fpu_kern_enter()	((void)0)
52bd9707e0Sriastradh #define	fpu_kern_leave()	((void)0)
53bd9707e0Sriastradh #endif
540a776e17Sriastradh 
550a776e17Sriastradh static void
aes_neon_setenckey_impl(struct aesenc * enc,const uint8_t * key,uint32_t nrounds)560a776e17Sriastradh aes_neon_setenckey_impl(struct aesenc *enc, const uint8_t *key,
570a776e17Sriastradh     uint32_t nrounds)
580a776e17Sriastradh {
590a776e17Sriastradh 
600a776e17Sriastradh 	fpu_kern_enter();
610a776e17Sriastradh 	aes_neon_setenckey(enc, key, nrounds);
620a776e17Sriastradh 	fpu_kern_leave();
630a776e17Sriastradh }
640a776e17Sriastradh 
650a776e17Sriastradh static void
aes_neon_setdeckey_impl(struct aesdec * dec,const uint8_t * key,uint32_t nrounds)660a776e17Sriastradh aes_neon_setdeckey_impl(struct aesdec *dec, const uint8_t *key,
670a776e17Sriastradh     uint32_t nrounds)
680a776e17Sriastradh {
690a776e17Sriastradh 
700a776e17Sriastradh 	fpu_kern_enter();
710a776e17Sriastradh 	aes_neon_setdeckey(dec, key, nrounds);
720a776e17Sriastradh 	fpu_kern_leave();
730a776e17Sriastradh }
740a776e17Sriastradh 
750a776e17Sriastradh static void
aes_neon_enc_impl(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)760a776e17Sriastradh aes_neon_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
770a776e17Sriastradh     uint8_t out[static 16], uint32_t nrounds)
780a776e17Sriastradh {
790a776e17Sriastradh 
800a776e17Sriastradh 	fpu_kern_enter();
810a776e17Sriastradh 	aes_neon_enc(enc, in, out, nrounds);
820a776e17Sriastradh 	fpu_kern_leave();
830a776e17Sriastradh }
840a776e17Sriastradh 
850a776e17Sriastradh static void
aes_neon_dec_impl(const struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)860a776e17Sriastradh aes_neon_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
870a776e17Sriastradh     uint8_t out[static 16], uint32_t nrounds)
880a776e17Sriastradh {
890a776e17Sriastradh 
900a776e17Sriastradh 	fpu_kern_enter();
910a776e17Sriastradh 	aes_neon_dec(dec, in, out, nrounds);
920a776e17Sriastradh 	fpu_kern_leave();
930a776e17Sriastradh }
940a776e17Sriastradh 
950a776e17Sriastradh static void
aes_neon_cbc_enc_impl(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)960a776e17Sriastradh aes_neon_cbc_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
970a776e17Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
980a776e17Sriastradh     uint32_t nrounds)
990a776e17Sriastradh {
1000a776e17Sriastradh 
1010a776e17Sriastradh 	if (nbytes == 0)
1020a776e17Sriastradh 		return;
1030a776e17Sriastradh 	fpu_kern_enter();
1040a776e17Sriastradh 	aes_neon_cbc_enc(enc, in, out, nbytes, iv, nrounds);
1050a776e17Sriastradh 	fpu_kern_leave();
1060a776e17Sriastradh }
1070a776e17Sriastradh 
1080a776e17Sriastradh static void
aes_neon_cbc_dec_impl(const struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)1090a776e17Sriastradh aes_neon_cbc_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
1100a776e17Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
1110a776e17Sriastradh     uint32_t nrounds)
1120a776e17Sriastradh {
1130a776e17Sriastradh 
1140a776e17Sriastradh 	if (nbytes == 0)
1150a776e17Sriastradh 		return;
1160a776e17Sriastradh 	fpu_kern_enter();
1170a776e17Sriastradh 	aes_neon_cbc_dec(dec, in, out, nbytes, iv, nrounds);
1180a776e17Sriastradh 	fpu_kern_leave();
1190a776e17Sriastradh }
1200a776e17Sriastradh 
1210a776e17Sriastradh static void
aes_neon_xts_enc_impl(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)1220a776e17Sriastradh aes_neon_xts_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
1230a776e17Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
1240a776e17Sriastradh     uint32_t nrounds)
1250a776e17Sriastradh {
1260a776e17Sriastradh 
1270a776e17Sriastradh 	if (nbytes == 0)
1280a776e17Sriastradh 		return;
1290a776e17Sriastradh 	fpu_kern_enter();
1300a776e17Sriastradh 	aes_neon_xts_enc(enc, in, out, nbytes, iv, nrounds);
1310a776e17Sriastradh 	fpu_kern_leave();
1320a776e17Sriastradh }
1330a776e17Sriastradh 
1340a776e17Sriastradh static void
aes_neon_xts_dec_impl(const struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)1350a776e17Sriastradh aes_neon_xts_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
1360a776e17Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
1370a776e17Sriastradh     uint32_t nrounds)
1380a776e17Sriastradh {
1390a776e17Sriastradh 
1400a776e17Sriastradh 	if (nbytes == 0)
1410a776e17Sriastradh 		return;
1420a776e17Sriastradh 	fpu_kern_enter();
1430a776e17Sriastradh 	aes_neon_xts_dec(dec, in, out, nbytes, iv, nrounds);
1440a776e17Sriastradh 	fpu_kern_leave();
1450a776e17Sriastradh }
1460a776e17Sriastradh 
147f8ae4137Sriastradh static void
aes_neon_cbcmac_update1_impl(const struct aesenc * enc,const uint8_t in[static16],size_t nbytes,uint8_t auth[static16],uint32_t nrounds)148f8ae4137Sriastradh aes_neon_cbcmac_update1_impl(const struct aesenc *enc,
149f8ae4137Sriastradh     const uint8_t in[static 16], size_t nbytes, uint8_t auth[static 16],
150f8ae4137Sriastradh     uint32_t nrounds)
151f8ae4137Sriastradh {
152f8ae4137Sriastradh 
153f8ae4137Sriastradh 	fpu_kern_enter();
154f8ae4137Sriastradh 	aes_neon_cbcmac_update1(enc, in, nbytes, auth, nrounds);
155f8ae4137Sriastradh 	fpu_kern_leave();
156f8ae4137Sriastradh }
157f8ae4137Sriastradh 
158f8ae4137Sriastradh static void
aes_neon_ccm_enc1_impl(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t authctr[static32],uint32_t nrounds)159f8ae4137Sriastradh aes_neon_ccm_enc1_impl(const struct aesenc *enc, const uint8_t in[static 16],
160f8ae4137Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
161f8ae4137Sriastradh     uint32_t nrounds)
162f8ae4137Sriastradh {
163f8ae4137Sriastradh 
164f8ae4137Sriastradh 	fpu_kern_enter();
165f8ae4137Sriastradh 	aes_neon_ccm_enc1(enc, in, out, nbytes, authctr, nrounds);
166f8ae4137Sriastradh 	fpu_kern_leave();
167f8ae4137Sriastradh }
168f8ae4137Sriastradh 
169f8ae4137Sriastradh static void
aes_neon_ccm_dec1_impl(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t authctr[static32],uint32_t nrounds)170f8ae4137Sriastradh aes_neon_ccm_dec1_impl(const struct aesenc *enc, const uint8_t in[static 16],
171f8ae4137Sriastradh     uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
172f8ae4137Sriastradh     uint32_t nrounds)
173f8ae4137Sriastradh {
174f8ae4137Sriastradh 
175f8ae4137Sriastradh 	fpu_kern_enter();
176f8ae4137Sriastradh 	aes_neon_ccm_dec1(enc, in, out, nbytes, authctr, nrounds);
177f8ae4137Sriastradh 	fpu_kern_leave();
178f8ae4137Sriastradh }
179f8ae4137Sriastradh 
1800a776e17Sriastradh static int
aes_neon_probe(void)1810a776e17Sriastradh aes_neon_probe(void)
1820a776e17Sriastradh {
1830a776e17Sriastradh #ifdef __aarch64__
1840a776e17Sriastradh 	struct aarch64_sysctl_cpu_id *id;
1850a776e17Sriastradh #endif
1860a776e17Sriastradh 	int result = 0;
1870a776e17Sriastradh 
1880a776e17Sriastradh 	/* Verify that the CPU supports NEON.  */
1890a776e17Sriastradh #ifdef __aarch64__
190bd9707e0Sriastradh #ifdef _KERNEL
1910a776e17Sriastradh 	id = &curcpu()->ci_id;
192bd9707e0Sriastradh #else
193bd9707e0Sriastradh 	struct aarch64_sysctl_cpu_id ids;
194bd9707e0Sriastradh 	size_t idlen;
195bd9707e0Sriastradh 	id = &ids;
196bd9707e0Sriastradh 	idlen = sizeof ids;
197bd9707e0Sriastradh 	if (sysctlbyname("machdep.cpu0.cpu_id", id, &idlen, NULL, 0))
198bd9707e0Sriastradh 		return -1;
199bd9707e0Sriastradh 	if (idlen != sizeof ids)
200bd9707e0Sriastradh 		return -1;
201bd9707e0Sriastradh #endif
2020a776e17Sriastradh 	switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
203*4a48ef14Sjmcneill 	case ID_AA64PFR0_EL1_ADV_SIMD_NONE:
2040a776e17Sriastradh 		return -1;
205*4a48ef14Sjmcneill 	default:
206*4a48ef14Sjmcneill 		break;
2070a776e17Sriastradh 	}
2080a776e17Sriastradh #else
209bd9707e0Sriastradh #ifdef _KERNEL
2100a776e17Sriastradh 	if (!cpu_neon_present)
2110a776e17Sriastradh 		return -1;
212bd9707e0Sriastradh #else
213bd9707e0Sriastradh 	int neon;
214bd9707e0Sriastradh 	size_t neonlen = sizeof neon;
215bd9707e0Sriastradh 	if (0 && sysctlbyname("machdep.neon_present", &neon, &neonlen, NULL, 0))
216bd9707e0Sriastradh 		return -1;
217bd9707e0Sriastradh 	if (0 && !neon)
218bd9707e0Sriastradh 		return -1;
219bd9707e0Sriastradh #endif
2200a776e17Sriastradh #endif
2210a776e17Sriastradh 
2220a776e17Sriastradh 	fpu_kern_enter();
2230a776e17Sriastradh 	result = aes_neon_selftest();
2240a776e17Sriastradh 	fpu_kern_leave();
2250a776e17Sriastradh 
2260a776e17Sriastradh 	return result;
2270a776e17Sriastradh }
2280a776e17Sriastradh 
2290a776e17Sriastradh struct aes_impl aes_neon_impl = {
2300a776e17Sriastradh 	.ai_name = "ARM NEON vpaes",
2310a776e17Sriastradh 	.ai_probe = aes_neon_probe,
2320a776e17Sriastradh 	.ai_setenckey = aes_neon_setenckey_impl,
2330a776e17Sriastradh 	.ai_setdeckey = aes_neon_setdeckey_impl,
2340a776e17Sriastradh 	.ai_enc = aes_neon_enc_impl,
2350a776e17Sriastradh 	.ai_dec = aes_neon_dec_impl,
2360a776e17Sriastradh 	.ai_cbc_enc = aes_neon_cbc_enc_impl,
2370a776e17Sriastradh 	.ai_cbc_dec = aes_neon_cbc_dec_impl,
2380a776e17Sriastradh 	.ai_xts_enc = aes_neon_xts_enc_impl,
2390a776e17Sriastradh 	.ai_xts_dec = aes_neon_xts_dec_impl,
240f8ae4137Sriastradh 	.ai_cbcmac_update1 = aes_neon_cbcmac_update1_impl,
241f8ae4137Sriastradh 	.ai_ccm_enc1 = aes_neon_ccm_enc1_impl,
242f8ae4137Sriastradh 	.ai_ccm_dec1 = aes_neon_ccm_dec1_impl,
2430a776e17Sriastradh };
244