11.1Sriastrad/*	$NetBSD: aes_sse2_4x32_impl.c,v 1.1 2025/11/23 22:48:26 riastradh Exp $	*/
21.1Sriastrad
31.1Sriastrad/*-
41.1Sriastrad * Copyright (c) 2025 The NetBSD Foundation, Inc.
51.1Sriastrad * All rights reserved.
61.1Sriastrad *
71.1Sriastrad * Redistribution and use in source and binary forms, with or without
81.1Sriastrad * modification, are permitted provided that the following conditions
91.1Sriastrad * are met:
101.1Sriastrad * 1. Redistributions of source code must retain the above copyright
111.1Sriastrad *    notice, this list of conditions and the following disclaimer.
121.1Sriastrad * 2. Redistributions in binary form must reproduce the above copyright
131.1Sriastrad *    notice, this list of conditions and the following disclaimer in the
141.1Sriastrad *    documentation and/or other materials provided with the distribution.
151.1Sriastrad *
161.1Sriastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Sriastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Sriastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Sriastrad * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Sriastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Sriastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Sriastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Sriastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Sriastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Sriastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Sriastrad * POSSIBILITY OF SUCH DAMAGE.
271.1Sriastrad */
281.1Sriastrad
291.1Sriastrad#include <sys/cdefs.h>
301.1Sriastrad__KERNEL_RCSID(1, "$NetBSD: aes_sse2_4x32_impl.c,v 1.1 2025/11/23 22:48:26 riastradh Exp $");
311.1Sriastrad
321.1Sriastrad#include <sys/types.h>
331.1Sriastrad#include <sys/endian.h>
341.1Sriastrad
351.1Sriastrad#include <crypto/aes/aes.h>
361.1Sriastrad#include <crypto/aes/aes_impl.h>
371.1Sriastrad#include <crypto/aes/arch/x86/aes_sse2_4x32.h>
381.1Sriastrad
391.1Sriastrad#ifdef _KERNEL
401.1Sriastrad#include <x86/cpu.h>
411.1Sriastrad#include <x86/cpuvar.h>
421.1Sriastrad#include <x86/fpu.h>
431.1Sriastrad#include <x86/specialreg.h>
441.1Sriastrad#else
451.1Sriastrad#include <cpuid.h>
461.1Sriastrad#define	fpu_kern_enter()	((void)0)
471.1Sriastrad#define	fpu_kern_leave()	((void)0)
481.1Sriastrad#endif
491.1Sriastrad
501.1Sriastrad#include "aes_sse2_4x32_subr.h"
511.1Sriastrad
521.1Sriastradstatic void
531.1Sriastradaes_sse2_4x32_setenckey_impl(struct aesenc *enc, const uint8_t *key,
541.1Sriastrad    uint32_t nrounds)
551.1Sriastrad{
561.1Sriastrad
571.1Sriastrad	fpu_kern_enter();
581.1Sriastrad	aes_sse2_4x32_setkey(enc->aese_aes.aes_rk, key, nrounds);
591.1Sriastrad	fpu_kern_leave();
601.1Sriastrad}
611.1Sriastrad
621.1Sriastradstatic void
631.1Sriastradaes_sse2_4x32_setdeckey_impl(struct aesdec *dec, const uint8_t *key,
641.1Sriastrad    uint32_t nrounds)
651.1Sriastrad{
661.1Sriastrad
671.1Sriastrad	fpu_kern_enter();
681.1Sriastrad	/*
691.1Sriastrad	 * BearSSL computes InvMixColumns on the fly -- no need for
701.1Sriastrad	 * distinct decryption round keys.
711.1Sriastrad	 */
721.1Sriastrad	aes_sse2_4x32_setkey(dec->aesd_aes.aes_rk, key, nrounds);
731.1Sriastrad	fpu_kern_leave();
741.1Sriastrad}
751.1Sriastrad
761.1Sriastradstatic void
771.1Sriastradaes_sse2_4x32_enc_impl(const struct aesenc *enc, const uint8_t in[static 16],
781.1Sriastrad    uint8_t out[static 16], uint32_t nrounds)
791.1Sriastrad{
801.1Sriastrad
811.1Sriastrad	fpu_kern_enter();
821.1Sriastrad	aes_sse2_4x32_enc(enc, in, out, nrounds);
831.1Sriastrad	fpu_kern_leave();
841.1Sriastrad}
851.1Sriastrad
861.1Sriastradstatic void
871.1Sriastradaes_sse2_4x32_dec_impl(const struct aesdec *dec, const uint8_t in[static 16],
881.1Sriastrad    uint8_t out[static 16], uint32_t nrounds)
891.1Sriastrad{
901.1Sriastrad
911.1Sriastrad	fpu_kern_enter();
921.1Sriastrad	aes_sse2_4x32_dec(dec, in, out, nrounds);
931.1Sriastrad	fpu_kern_leave();
941.1Sriastrad}
951.1Sriastrad
961.1Sriastradstatic void
971.1Sriastradaes_sse2_4x32_cbc_enc_impl(const struct aesenc *enc,
981.1Sriastrad    const uint8_t in[static 16], uint8_t out[static 16],
991.1Sriastrad    size_t nbytes, uint8_t iv[static 16], uint32_t nrounds)
1001.1Sriastrad{
1011.1Sriastrad
1021.1Sriastrad	if (nbytes == 0)
1031.1Sriastrad		return;
1041.1Sriastrad	fpu_kern_enter();
1051.1Sriastrad	aes_sse2_4x32_cbc_enc(enc, in, out, nbytes, iv, nrounds);
1061.1Sriastrad	fpu_kern_leave();
1071.1Sriastrad}
1081.1Sriastrad
1091.1Sriastradstatic void
1101.1Sriastradaes_sse2_4x32_cbc_dec_impl(const struct aesdec *dec,
1111.1Sriastrad    const uint8_t in[static 16], uint8_t out[static 16],
1121.1Sriastrad    size_t nbytes, uint8_t iv[static 16], uint32_t nrounds)
1131.1Sriastrad{
1141.1Sriastrad
1151.1Sriastrad	if (nbytes == 0)
1161.1Sriastrad		return;
1171.1Sriastrad	fpu_kern_enter();
1181.1Sriastrad	aes_sse2_4x32_cbc_dec(dec, in, out, nbytes, iv, nrounds);
1191.1Sriastrad	fpu_kern_leave();
1201.1Sriastrad}
1211.1Sriastrad
1221.1Sriastradstatic void
1231.1Sriastradaes_sse2_4x32_xts_enc_impl(const struct aesenc *enc,
1241.1Sriastrad    const uint8_t in[static 16], uint8_t out[static 16],
1251.1Sriastrad    size_t nbytes, uint8_t tweak[static 16], uint32_t nrounds)
1261.1Sriastrad{
1271.1Sriastrad
1281.1Sriastrad	if (nbytes == 0)
1291.1Sriastrad		return;
1301.1Sriastrad	fpu_kern_enter();
1311.1Sriastrad	aes_sse2_4x32_xts_enc(enc, in, out, nbytes, tweak, nrounds);
1321.1Sriastrad	fpu_kern_leave();
1331.1Sriastrad}
1341.1Sriastrad
1351.1Sriastradstatic void
1361.1Sriastradaes_sse2_4x32_xts_dec_impl(const struct aesdec *dec,
1371.1Sriastrad    const uint8_t in[static 16], uint8_t out[static 16],
1381.1Sriastrad    size_t nbytes, uint8_t tweak[static 16], uint32_t nrounds)
1391.1Sriastrad{
1401.1Sriastrad
1411.1Sriastrad	if (nbytes == 0)
1421.1Sriastrad		return;
1431.1Sriastrad	fpu_kern_enter();
1441.1Sriastrad	aes_sse2_4x32_xts_dec(dec, in, out, nbytes, tweak, nrounds);
1451.1Sriastrad	fpu_kern_leave();
1461.1Sriastrad}
1471.1Sriastrad
1481.1Sriastradstatic void
1491.1Sriastradaes_sse2_4x32_cbcmac_update1_impl(const struct aesenc *enc,
1501.1Sriastrad    const uint8_t in[static 16], size_t nbytes, uint8_t auth[static 16],
1511.1Sriastrad    uint32_t nrounds)
1521.1Sriastrad{
1531.1Sriastrad
1541.1Sriastrad	fpu_kern_enter();
1551.1Sriastrad	aes_sse2_4x32_cbcmac_update1(enc, in, nbytes, auth, nrounds);
1561.1Sriastrad	fpu_kern_leave();
1571.1Sriastrad}
1581.1Sriastrad
1591.1Sriastradstatic void
1601.1Sriastradaes_sse2_4x32_ccm_enc1_impl(const struct aesenc *enc,
1611.1Sriastrad    const uint8_t *in, uint8_t *out,
1621.1Sriastrad    size_t nbytes, uint8_t authctr[32], uint32_t nrounds)
1631.1Sriastrad{
1641.1Sriastrad
1651.1Sriastrad	fpu_kern_enter();
1661.1Sriastrad	aes_sse2_4x32_ccm_enc1(enc, in, out, nbytes, authctr, nrounds);
1671.1Sriastrad	fpu_kern_leave();
1681.1Sriastrad}
1691.1Sriastrad
1701.1Sriastradstatic void
1711.1Sriastradaes_sse2_4x32_ccm_dec1_impl(const struct aesenc *enc,
1721.1Sriastrad    const uint8_t *in, uint8_t *out,
1731.1Sriastrad    size_t nbytes, uint8_t authctr[32], uint32_t nrounds)
1741.1Sriastrad{
1751.1Sriastrad
1761.1Sriastrad	fpu_kern_enter();
1771.1Sriastrad	aes_sse2_4x32_ccm_dec1(enc, in, out, nbytes, authctr, nrounds);
1781.1Sriastrad	fpu_kern_leave();
1791.1Sriastrad}
1801.1Sriastrad
1811.1Sriastradstatic int
1821.1Sriastradaes_sse2_4x32_probe(void)
1831.1Sriastrad{
1841.1Sriastrad	int result = 0;
1851.1Sriastrad
1861.1Sriastrad	/* Verify that the CPU supports SSE and SSE2.  */
1871.1Sriastrad#ifdef _KERNEL
1881.1Sriastrad	if (!i386_has_sse)
1891.1Sriastrad		return -1;
1901.1Sriastrad	if (!i386_has_sse2)
1911.1Sriastrad		return -1;
1921.1Sriastrad#else
1931.1Sriastrad	unsigned eax, ebx, ecx, edx;
1941.1Sriastrad	if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
1951.1Sriastrad		return -1;
1961.1Sriastrad	if ((edx & bit_SSE) == 0)
1971.1Sriastrad		return -1;
1981.1Sriastrad	if ((edx & bit_SSE2) == 0)
1991.1Sriastrad		return -1;
2001.1Sriastrad#endif
2011.1Sriastrad
2021.1Sriastrad	fpu_kern_enter();
2031.1Sriastrad	result = aes_sse2_4x32_selftest();
2041.1Sriastrad	fpu_kern_leave();
2051.1Sriastrad
2061.1Sriastrad	return result;
2071.1Sriastrad}
2081.1Sriastrad
2091.1Sriastradstruct aes_impl aes_sse2_4x32_impl = {
2101.1Sriastrad	.ai_name = "Intel SSE2 4x32 bitsliced",
2111.1Sriastrad	.ai_probe = aes_sse2_4x32_probe,
2121.1Sriastrad	.ai_setenckey = aes_sse2_4x32_setenckey_impl,
2131.1Sriastrad	.ai_setdeckey = aes_sse2_4x32_setdeckey_impl,
2141.1Sriastrad	.ai_enc = aes_sse2_4x32_enc_impl,
2151.1Sriastrad	.ai_dec = aes_sse2_4x32_dec_impl,
2161.1Sriastrad	.ai_cbc_enc = aes_sse2_4x32_cbc_enc_impl,
2171.1Sriastrad	.ai_cbc_dec = aes_sse2_4x32_cbc_dec_impl,
2181.1Sriastrad	.ai_xts_enc = aes_sse2_4x32_xts_enc_impl,
2191.1Sriastrad	.ai_xts_dec = aes_sse2_4x32_xts_dec_impl,
2201.1Sriastrad	.ai_cbcmac_update1 = aes_sse2_4x32_cbcmac_update1_impl,
2211.1Sriastrad	.ai_ccm_enc1 = aes_sse2_4x32_ccm_enc1_impl,
2221.1Sriastrad	.ai_ccm_dec1 = aes_sse2_4x32_ccm_dec1_impl,
2231.1Sriastrad};
224