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