18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * x64 SIMD accelerated ChaCha and XChaCha stream ciphers, 48c2ecf20Sopenharmony_ci * including ChaCha20 (RFC7539) 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2015 Martin Willi 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <crypto/algapi.h> 108c2ecf20Sopenharmony_ci#include <crypto/internal/chacha.h> 118c2ecf20Sopenharmony_ci#include <crypto/internal/simd.h> 128c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/sizes.h> 168c2ecf20Sopenharmony_ci#include <asm/simd.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ciasmlinkage void chacha_block_xor_ssse3(u32 *state, u8 *dst, const u8 *src, 198c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 208c2ecf20Sopenharmony_ciasmlinkage void chacha_4block_xor_ssse3(u32 *state, u8 *dst, const u8 *src, 218c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 228c2ecf20Sopenharmony_ciasmlinkage void hchacha_block_ssse3(const u32 *state, u32 *out, int nrounds); 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciasmlinkage void chacha_2block_xor_avx2(u32 *state, u8 *dst, const u8 *src, 258c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 268c2ecf20Sopenharmony_ciasmlinkage void chacha_4block_xor_avx2(u32 *state, u8 *dst, const u8 *src, 278c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 288c2ecf20Sopenharmony_ciasmlinkage void chacha_8block_xor_avx2(u32 *state, u8 *dst, const u8 *src, 298c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ciasmlinkage void chacha_2block_xor_avx512vl(u32 *state, u8 *dst, const u8 *src, 328c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 338c2ecf20Sopenharmony_ciasmlinkage void chacha_4block_xor_avx512vl(u32 *state, u8 *dst, const u8 *src, 348c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 358c2ecf20Sopenharmony_ciasmlinkage void chacha_8block_xor_avx512vl(u32 *state, u8 *dst, const u8 *src, 368c2ecf20Sopenharmony_ci unsigned int len, int nrounds); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_simd); 398c2ecf20Sopenharmony_cistatic __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_avx2); 408c2ecf20Sopenharmony_cistatic __ro_after_init DEFINE_STATIC_KEY_FALSE(chacha_use_avx512vl); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic unsigned int chacha_advance(unsigned int len, unsigned int maxblocks) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci len = min(len, maxblocks * CHACHA_BLOCK_SIZE); 458c2ecf20Sopenharmony_ci return round_up(len, CHACHA_BLOCK_SIZE) / CHACHA_BLOCK_SIZE; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic void chacha_dosimd(u32 *state, u8 *dst, const u8 *src, 498c2ecf20Sopenharmony_ci unsigned int bytes, int nrounds) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_AS_AVX512) && 528c2ecf20Sopenharmony_ci static_branch_likely(&chacha_use_avx512vl)) { 538c2ecf20Sopenharmony_ci while (bytes >= CHACHA_BLOCK_SIZE * 8) { 548c2ecf20Sopenharmony_ci chacha_8block_xor_avx512vl(state, dst, src, bytes, 558c2ecf20Sopenharmony_ci nrounds); 568c2ecf20Sopenharmony_ci bytes -= CHACHA_BLOCK_SIZE * 8; 578c2ecf20Sopenharmony_ci src += CHACHA_BLOCK_SIZE * 8; 588c2ecf20Sopenharmony_ci dst += CHACHA_BLOCK_SIZE * 8; 598c2ecf20Sopenharmony_ci state[12] += 8; 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE * 4) { 628c2ecf20Sopenharmony_ci chacha_8block_xor_avx512vl(state, dst, src, bytes, 638c2ecf20Sopenharmony_ci nrounds); 648c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 8); 658c2ecf20Sopenharmony_ci return; 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE * 2) { 688c2ecf20Sopenharmony_ci chacha_4block_xor_avx512vl(state, dst, src, bytes, 698c2ecf20Sopenharmony_ci nrounds); 708c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 4); 718c2ecf20Sopenharmony_ci return; 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci if (bytes) { 748c2ecf20Sopenharmony_ci chacha_2block_xor_avx512vl(state, dst, src, bytes, 758c2ecf20Sopenharmony_ci nrounds); 768c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 2); 778c2ecf20Sopenharmony_ci return; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (static_branch_likely(&chacha_use_avx2)) { 828c2ecf20Sopenharmony_ci while (bytes >= CHACHA_BLOCK_SIZE * 8) { 838c2ecf20Sopenharmony_ci chacha_8block_xor_avx2(state, dst, src, bytes, nrounds); 848c2ecf20Sopenharmony_ci bytes -= CHACHA_BLOCK_SIZE * 8; 858c2ecf20Sopenharmony_ci src += CHACHA_BLOCK_SIZE * 8; 868c2ecf20Sopenharmony_ci dst += CHACHA_BLOCK_SIZE * 8; 878c2ecf20Sopenharmony_ci state[12] += 8; 888c2ecf20Sopenharmony_ci } 898c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE * 4) { 908c2ecf20Sopenharmony_ci chacha_8block_xor_avx2(state, dst, src, bytes, nrounds); 918c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 8); 928c2ecf20Sopenharmony_ci return; 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE * 2) { 958c2ecf20Sopenharmony_ci chacha_4block_xor_avx2(state, dst, src, bytes, nrounds); 968c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 4); 978c2ecf20Sopenharmony_ci return; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE) { 1008c2ecf20Sopenharmony_ci chacha_2block_xor_avx2(state, dst, src, bytes, nrounds); 1018c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 2); 1028c2ecf20Sopenharmony_ci return; 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci } 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci while (bytes >= CHACHA_BLOCK_SIZE * 4) { 1078c2ecf20Sopenharmony_ci chacha_4block_xor_ssse3(state, dst, src, bytes, nrounds); 1088c2ecf20Sopenharmony_ci bytes -= CHACHA_BLOCK_SIZE * 4; 1098c2ecf20Sopenharmony_ci src += CHACHA_BLOCK_SIZE * 4; 1108c2ecf20Sopenharmony_ci dst += CHACHA_BLOCK_SIZE * 4; 1118c2ecf20Sopenharmony_ci state[12] += 4; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci if (bytes > CHACHA_BLOCK_SIZE) { 1148c2ecf20Sopenharmony_ci chacha_4block_xor_ssse3(state, dst, src, bytes, nrounds); 1158c2ecf20Sopenharmony_ci state[12] += chacha_advance(bytes, 4); 1168c2ecf20Sopenharmony_ci return; 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci if (bytes) { 1198c2ecf20Sopenharmony_ci chacha_block_xor_ssse3(state, dst, src, bytes, nrounds); 1208c2ecf20Sopenharmony_ci state[12]++; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_civoid hchacha_block_arch(const u32 *state, u32 *stream, int nrounds) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci if (!static_branch_likely(&chacha_use_simd) || !crypto_simd_usable()) { 1278c2ecf20Sopenharmony_ci hchacha_block_generic(state, stream, nrounds); 1288c2ecf20Sopenharmony_ci } else { 1298c2ecf20Sopenharmony_ci kernel_fpu_begin(); 1308c2ecf20Sopenharmony_ci hchacha_block_ssse3(state, stream, nrounds); 1318c2ecf20Sopenharmony_ci kernel_fpu_end(); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci} 1348c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hchacha_block_arch); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_civoid chacha_init_arch(u32 *state, const u32 *key, const u8 *iv) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci chacha_init_generic(state, key, iv); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ciEXPORT_SYMBOL(chacha_init_arch); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_civoid chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes, 1438c2ecf20Sopenharmony_ci int nrounds) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci if (!static_branch_likely(&chacha_use_simd) || !crypto_simd_usable() || 1468c2ecf20Sopenharmony_ci bytes <= CHACHA_BLOCK_SIZE) 1478c2ecf20Sopenharmony_ci return chacha_crypt_generic(state, dst, src, bytes, nrounds); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci do { 1508c2ecf20Sopenharmony_ci unsigned int todo = min_t(unsigned int, bytes, SZ_4K); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci kernel_fpu_begin(); 1538c2ecf20Sopenharmony_ci chacha_dosimd(state, dst, src, todo, nrounds); 1548c2ecf20Sopenharmony_ci kernel_fpu_end(); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci bytes -= todo; 1578c2ecf20Sopenharmony_ci src += todo; 1588c2ecf20Sopenharmony_ci dst += todo; 1598c2ecf20Sopenharmony_ci } while (bytes); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(chacha_crypt_arch); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic int chacha_simd_stream_xor(struct skcipher_request *req, 1648c2ecf20Sopenharmony_ci const struct chacha_ctx *ctx, const u8 *iv) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci u32 state[CHACHA_STATE_WORDS] __aligned(8); 1678c2ecf20Sopenharmony_ci struct skcipher_walk walk; 1688c2ecf20Sopenharmony_ci int err; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci chacha_init_generic(state, ctx->key, iv); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci while (walk.nbytes > 0) { 1758c2ecf20Sopenharmony_ci unsigned int nbytes = walk.nbytes; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci if (nbytes < walk.total) 1788c2ecf20Sopenharmony_ci nbytes = round_down(nbytes, walk.stride); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci if (!static_branch_likely(&chacha_use_simd) || 1818c2ecf20Sopenharmony_ci !crypto_simd_usable()) { 1828c2ecf20Sopenharmony_ci chacha_crypt_generic(state, walk.dst.virt.addr, 1838c2ecf20Sopenharmony_ci walk.src.virt.addr, nbytes, 1848c2ecf20Sopenharmony_ci ctx->nrounds); 1858c2ecf20Sopenharmony_ci } else { 1868c2ecf20Sopenharmony_ci kernel_fpu_begin(); 1878c2ecf20Sopenharmony_ci chacha_dosimd(state, walk.dst.virt.addr, 1888c2ecf20Sopenharmony_ci walk.src.virt.addr, nbytes, 1898c2ecf20Sopenharmony_ci ctx->nrounds); 1908c2ecf20Sopenharmony_ci kernel_fpu_end(); 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes - nbytes); 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci return err; 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic int chacha_simd(struct skcipher_request *req) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 2018c2ecf20Sopenharmony_ci struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci return chacha_simd_stream_xor(req, ctx, req->iv); 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic int xchacha_simd(struct skcipher_request *req) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 2098c2ecf20Sopenharmony_ci struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm); 2108c2ecf20Sopenharmony_ci u32 state[CHACHA_STATE_WORDS] __aligned(8); 2118c2ecf20Sopenharmony_ci struct chacha_ctx subctx; 2128c2ecf20Sopenharmony_ci u8 real_iv[16]; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci chacha_init_generic(state, ctx->key, req->iv); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci if (req->cryptlen > CHACHA_BLOCK_SIZE && crypto_simd_usable()) { 2178c2ecf20Sopenharmony_ci kernel_fpu_begin(); 2188c2ecf20Sopenharmony_ci hchacha_block_ssse3(state, subctx.key, ctx->nrounds); 2198c2ecf20Sopenharmony_ci kernel_fpu_end(); 2208c2ecf20Sopenharmony_ci } else { 2218c2ecf20Sopenharmony_ci hchacha_block_generic(state, subctx.key, ctx->nrounds); 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci subctx.nrounds = ctx->nrounds; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci memcpy(&real_iv[0], req->iv + 24, 8); 2268c2ecf20Sopenharmony_ci memcpy(&real_iv[8], req->iv + 16, 8); 2278c2ecf20Sopenharmony_ci return chacha_simd_stream_xor(req, &subctx, real_iv); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic struct skcipher_alg algs[] = { 2318c2ecf20Sopenharmony_ci { 2328c2ecf20Sopenharmony_ci .base.cra_name = "chacha20", 2338c2ecf20Sopenharmony_ci .base.cra_driver_name = "chacha20-simd", 2348c2ecf20Sopenharmony_ci .base.cra_priority = 300, 2358c2ecf20Sopenharmony_ci .base.cra_blocksize = 1, 2368c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct chacha_ctx), 2378c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 2408c2ecf20Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 2418c2ecf20Sopenharmony_ci .ivsize = CHACHA_IV_SIZE, 2428c2ecf20Sopenharmony_ci .chunksize = CHACHA_BLOCK_SIZE, 2438c2ecf20Sopenharmony_ci .setkey = chacha20_setkey, 2448c2ecf20Sopenharmony_ci .encrypt = chacha_simd, 2458c2ecf20Sopenharmony_ci .decrypt = chacha_simd, 2468c2ecf20Sopenharmony_ci }, { 2478c2ecf20Sopenharmony_ci .base.cra_name = "xchacha20", 2488c2ecf20Sopenharmony_ci .base.cra_driver_name = "xchacha20-simd", 2498c2ecf20Sopenharmony_ci .base.cra_priority = 300, 2508c2ecf20Sopenharmony_ci .base.cra_blocksize = 1, 2518c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct chacha_ctx), 2528c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 2558c2ecf20Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 2568c2ecf20Sopenharmony_ci .ivsize = XCHACHA_IV_SIZE, 2578c2ecf20Sopenharmony_ci .chunksize = CHACHA_BLOCK_SIZE, 2588c2ecf20Sopenharmony_ci .setkey = chacha20_setkey, 2598c2ecf20Sopenharmony_ci .encrypt = xchacha_simd, 2608c2ecf20Sopenharmony_ci .decrypt = xchacha_simd, 2618c2ecf20Sopenharmony_ci }, { 2628c2ecf20Sopenharmony_ci .base.cra_name = "xchacha12", 2638c2ecf20Sopenharmony_ci .base.cra_driver_name = "xchacha12-simd", 2648c2ecf20Sopenharmony_ci .base.cra_priority = 300, 2658c2ecf20Sopenharmony_ci .base.cra_blocksize = 1, 2668c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct chacha_ctx), 2678c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 2708c2ecf20Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 2718c2ecf20Sopenharmony_ci .ivsize = XCHACHA_IV_SIZE, 2728c2ecf20Sopenharmony_ci .chunksize = CHACHA_BLOCK_SIZE, 2738c2ecf20Sopenharmony_ci .setkey = chacha12_setkey, 2748c2ecf20Sopenharmony_ci .encrypt = xchacha_simd, 2758c2ecf20Sopenharmony_ci .decrypt = xchacha_simd, 2768c2ecf20Sopenharmony_ci }, 2778c2ecf20Sopenharmony_ci}; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic int __init chacha_simd_mod_init(void) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci if (!boot_cpu_has(X86_FEATURE_SSSE3)) 2828c2ecf20Sopenharmony_ci return 0; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci static_branch_enable(&chacha_use_simd); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci if (boot_cpu_has(X86_FEATURE_AVX) && 2878c2ecf20Sopenharmony_ci boot_cpu_has(X86_FEATURE_AVX2) && 2888c2ecf20Sopenharmony_ci cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) { 2898c2ecf20Sopenharmony_ci static_branch_enable(&chacha_use_avx2); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_AS_AVX512) && 2928c2ecf20Sopenharmony_ci boot_cpu_has(X86_FEATURE_AVX512VL) && 2938c2ecf20Sopenharmony_ci boot_cpu_has(X86_FEATURE_AVX512BW)) /* kmovq */ 2948c2ecf20Sopenharmony_ci static_branch_enable(&chacha_use_avx512vl); 2958c2ecf20Sopenharmony_ci } 2968c2ecf20Sopenharmony_ci return IS_REACHABLE(CONFIG_CRYPTO_SKCIPHER) ? 2978c2ecf20Sopenharmony_ci crypto_register_skciphers(algs, ARRAY_SIZE(algs)) : 0; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic void __exit chacha_simd_mod_fini(void) 3018c2ecf20Sopenharmony_ci{ 3028c2ecf20Sopenharmony_ci if (IS_REACHABLE(CONFIG_CRYPTO_SKCIPHER) && boot_cpu_has(X86_FEATURE_SSSE3)) 3038c2ecf20Sopenharmony_ci crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); 3048c2ecf20Sopenharmony_ci} 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cimodule_init(chacha_simd_mod_init); 3078c2ecf20Sopenharmony_cimodule_exit(chacha_simd_mod_fini); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 3108c2ecf20Sopenharmony_ciMODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); 3118c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (x64 SIMD accelerated)"); 3128c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("chacha20"); 3138c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("chacha20-simd"); 3148c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("xchacha20"); 3158c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("xchacha20-simd"); 3168c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("xchacha12"); 3178c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("xchacha12-simd"); 318