162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/arch/arm64/crypto/aes-glue.c - wrapper code for ARMv8 AES 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/neon.h> 962306a36Sopenharmony_ci#include <asm/hwcap.h> 1062306a36Sopenharmony_ci#include <asm/simd.h> 1162306a36Sopenharmony_ci#include <crypto/aes.h> 1262306a36Sopenharmony_ci#include <crypto/ctr.h> 1362306a36Sopenharmony_ci#include <crypto/sha2.h> 1462306a36Sopenharmony_ci#include <crypto/internal/hash.h> 1562306a36Sopenharmony_ci#include <crypto/internal/simd.h> 1662306a36Sopenharmony_ci#include <crypto/internal/skcipher.h> 1762306a36Sopenharmony_ci#include <crypto/scatterwalk.h> 1862306a36Sopenharmony_ci#include <linux/module.h> 1962306a36Sopenharmony_ci#include <linux/cpufeature.h> 2062306a36Sopenharmony_ci#include <crypto/xts.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include "aes-ce-setkey.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifdef USE_V8_CRYPTO_EXTENSIONS 2562306a36Sopenharmony_ci#define MODE "ce" 2662306a36Sopenharmony_ci#define PRIO 300 2762306a36Sopenharmony_ci#define aes_expandkey ce_aes_expandkey 2862306a36Sopenharmony_ci#define aes_ecb_encrypt ce_aes_ecb_encrypt 2962306a36Sopenharmony_ci#define aes_ecb_decrypt ce_aes_ecb_decrypt 3062306a36Sopenharmony_ci#define aes_cbc_encrypt ce_aes_cbc_encrypt 3162306a36Sopenharmony_ci#define aes_cbc_decrypt ce_aes_cbc_decrypt 3262306a36Sopenharmony_ci#define aes_cbc_cts_encrypt ce_aes_cbc_cts_encrypt 3362306a36Sopenharmony_ci#define aes_cbc_cts_decrypt ce_aes_cbc_cts_decrypt 3462306a36Sopenharmony_ci#define aes_essiv_cbc_encrypt ce_aes_essiv_cbc_encrypt 3562306a36Sopenharmony_ci#define aes_essiv_cbc_decrypt ce_aes_essiv_cbc_decrypt 3662306a36Sopenharmony_ci#define aes_ctr_encrypt ce_aes_ctr_encrypt 3762306a36Sopenharmony_ci#define aes_xctr_encrypt ce_aes_xctr_encrypt 3862306a36Sopenharmony_ci#define aes_xts_encrypt ce_aes_xts_encrypt 3962306a36Sopenharmony_ci#define aes_xts_decrypt ce_aes_xts_decrypt 4062306a36Sopenharmony_ci#define aes_mac_update ce_aes_mac_update 4162306a36Sopenharmony_ciMODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 Crypto Extensions"); 4262306a36Sopenharmony_ci#else 4362306a36Sopenharmony_ci#define MODE "neon" 4462306a36Sopenharmony_ci#define PRIO 200 4562306a36Sopenharmony_ci#define aes_ecb_encrypt neon_aes_ecb_encrypt 4662306a36Sopenharmony_ci#define aes_ecb_decrypt neon_aes_ecb_decrypt 4762306a36Sopenharmony_ci#define aes_cbc_encrypt neon_aes_cbc_encrypt 4862306a36Sopenharmony_ci#define aes_cbc_decrypt neon_aes_cbc_decrypt 4962306a36Sopenharmony_ci#define aes_cbc_cts_encrypt neon_aes_cbc_cts_encrypt 5062306a36Sopenharmony_ci#define aes_cbc_cts_decrypt neon_aes_cbc_cts_decrypt 5162306a36Sopenharmony_ci#define aes_essiv_cbc_encrypt neon_aes_essiv_cbc_encrypt 5262306a36Sopenharmony_ci#define aes_essiv_cbc_decrypt neon_aes_essiv_cbc_decrypt 5362306a36Sopenharmony_ci#define aes_ctr_encrypt neon_aes_ctr_encrypt 5462306a36Sopenharmony_ci#define aes_xctr_encrypt neon_aes_xctr_encrypt 5562306a36Sopenharmony_ci#define aes_xts_encrypt neon_aes_xts_encrypt 5662306a36Sopenharmony_ci#define aes_xts_decrypt neon_aes_xts_decrypt 5762306a36Sopenharmony_ci#define aes_mac_update neon_aes_mac_update 5862306a36Sopenharmony_ciMODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 NEON"); 5962306a36Sopenharmony_ci#endif 6062306a36Sopenharmony_ci#if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS) 6162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("ecb(aes)"); 6262306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("cbc(aes)"); 6362306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("ctr(aes)"); 6462306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("xts(aes)"); 6562306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("xctr(aes)"); 6662306a36Sopenharmony_ci#endif 6762306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("cts(cbc(aes))"); 6862306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("essiv(cbc(aes),sha256)"); 6962306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("cmac(aes)"); 7062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("xcbc(aes)"); 7162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("cbcmac(aes)"); 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciMODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); 7462306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* defined in aes-modes.S */ 7762306a36Sopenharmony_ciasmlinkage void aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[], 7862306a36Sopenharmony_ci int rounds, int blocks); 7962306a36Sopenharmony_ciasmlinkage void aes_ecb_decrypt(u8 out[], u8 const in[], u32 const rk[], 8062306a36Sopenharmony_ci int rounds, int blocks); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciasmlinkage void aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[], 8362306a36Sopenharmony_ci int rounds, int blocks, u8 iv[]); 8462306a36Sopenharmony_ciasmlinkage void aes_cbc_decrypt(u8 out[], u8 const in[], u32 const rk[], 8562306a36Sopenharmony_ci int rounds, int blocks, u8 iv[]); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciasmlinkage void aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[], 8862306a36Sopenharmony_ci int rounds, int bytes, u8 const iv[]); 8962306a36Sopenharmony_ciasmlinkage void aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[], 9062306a36Sopenharmony_ci int rounds, int bytes, u8 const iv[]); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ciasmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[], 9362306a36Sopenharmony_ci int rounds, int bytes, u8 ctr[]); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciasmlinkage void aes_xctr_encrypt(u8 out[], u8 const in[], u32 const rk[], 9662306a36Sopenharmony_ci int rounds, int bytes, u8 ctr[], int byte_ctr); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ciasmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[], 9962306a36Sopenharmony_ci int rounds, int bytes, u32 const rk2[], u8 iv[], 10062306a36Sopenharmony_ci int first); 10162306a36Sopenharmony_ciasmlinkage void aes_xts_decrypt(u8 out[], u8 const in[], u32 const rk1[], 10262306a36Sopenharmony_ci int rounds, int bytes, u32 const rk2[], u8 iv[], 10362306a36Sopenharmony_ci int first); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ciasmlinkage void aes_essiv_cbc_encrypt(u8 out[], u8 const in[], u32 const rk1[], 10662306a36Sopenharmony_ci int rounds, int blocks, u8 iv[], 10762306a36Sopenharmony_ci u32 const rk2[]); 10862306a36Sopenharmony_ciasmlinkage void aes_essiv_cbc_decrypt(u8 out[], u8 const in[], u32 const rk1[], 10962306a36Sopenharmony_ci int rounds, int blocks, u8 iv[], 11062306a36Sopenharmony_ci u32 const rk2[]); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ciasmlinkage int aes_mac_update(u8 const in[], u32 const rk[], int rounds, 11362306a36Sopenharmony_ci int blocks, u8 dg[], int enc_before, 11462306a36Sopenharmony_ci int enc_after); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistruct crypto_aes_xts_ctx { 11762306a36Sopenharmony_ci struct crypto_aes_ctx key1; 11862306a36Sopenharmony_ci struct crypto_aes_ctx __aligned(8) key2; 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistruct crypto_aes_essiv_cbc_ctx { 12262306a36Sopenharmony_ci struct crypto_aes_ctx key1; 12362306a36Sopenharmony_ci struct crypto_aes_ctx __aligned(8) key2; 12462306a36Sopenharmony_ci struct crypto_shash *hash; 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistruct mac_tfm_ctx { 12862306a36Sopenharmony_ci struct crypto_aes_ctx key; 12962306a36Sopenharmony_ci u8 __aligned(8) consts[]; 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistruct mac_desc_ctx { 13362306a36Sopenharmony_ci unsigned int len; 13462306a36Sopenharmony_ci u8 dg[AES_BLOCK_SIZE]; 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistatic int skcipher_aes_setkey(struct crypto_skcipher *tfm, const u8 *in_key, 13862306a36Sopenharmony_ci unsigned int key_len) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci return aes_expandkey(ctx, in_key, key_len); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic int __maybe_unused xts_set_key(struct crypto_skcipher *tfm, 14662306a36Sopenharmony_ci const u8 *in_key, unsigned int key_len) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci struct crypto_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm); 14962306a36Sopenharmony_ci int ret; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci ret = xts_verify_key(tfm, in_key, key_len); 15262306a36Sopenharmony_ci if (ret) 15362306a36Sopenharmony_ci return ret; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci ret = aes_expandkey(&ctx->key1, in_key, key_len / 2); 15662306a36Sopenharmony_ci if (!ret) 15762306a36Sopenharmony_ci ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2], 15862306a36Sopenharmony_ci key_len / 2); 15962306a36Sopenharmony_ci return ret; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic int __maybe_unused essiv_cbc_set_key(struct crypto_skcipher *tfm, 16362306a36Sopenharmony_ci const u8 *in_key, 16462306a36Sopenharmony_ci unsigned int key_len) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci struct crypto_aes_essiv_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 16762306a36Sopenharmony_ci u8 digest[SHA256_DIGEST_SIZE]; 16862306a36Sopenharmony_ci int ret; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci ret = aes_expandkey(&ctx->key1, in_key, key_len); 17162306a36Sopenharmony_ci if (ret) 17262306a36Sopenharmony_ci return ret; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci crypto_shash_tfm_digest(ctx->hash, in_key, key_len, digest); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci return aes_expandkey(&ctx->key2, digest, sizeof(digest)); 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic int __maybe_unused ecb_encrypt(struct skcipher_request *req) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 18262306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 18362306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 18462306a36Sopenharmony_ci struct skcipher_walk walk; 18562306a36Sopenharmony_ci unsigned int blocks; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) { 19062306a36Sopenharmony_ci kernel_neon_begin(); 19162306a36Sopenharmony_ci aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 19262306a36Sopenharmony_ci ctx->key_enc, rounds, blocks); 19362306a36Sopenharmony_ci kernel_neon_end(); 19462306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE); 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci return err; 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cistatic int __maybe_unused ecb_decrypt(struct skcipher_request *req) 20062306a36Sopenharmony_ci{ 20162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 20262306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 20362306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 20462306a36Sopenharmony_ci struct skcipher_walk walk; 20562306a36Sopenharmony_ci unsigned int blocks; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) { 21062306a36Sopenharmony_ci kernel_neon_begin(); 21162306a36Sopenharmony_ci aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 21262306a36Sopenharmony_ci ctx->key_dec, rounds, blocks); 21362306a36Sopenharmony_ci kernel_neon_end(); 21462306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE); 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci return err; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic int cbc_encrypt_walk(struct skcipher_request *req, 22062306a36Sopenharmony_ci struct skcipher_walk *walk) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 22362306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 22462306a36Sopenharmony_ci int err = 0, rounds = 6 + ctx->key_length / 4; 22562306a36Sopenharmony_ci unsigned int blocks; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci while ((blocks = (walk->nbytes / AES_BLOCK_SIZE))) { 22862306a36Sopenharmony_ci kernel_neon_begin(); 22962306a36Sopenharmony_ci aes_cbc_encrypt(walk->dst.virt.addr, walk->src.virt.addr, 23062306a36Sopenharmony_ci ctx->key_enc, rounds, blocks, walk->iv); 23162306a36Sopenharmony_ci kernel_neon_end(); 23262306a36Sopenharmony_ci err = skcipher_walk_done(walk, walk->nbytes % AES_BLOCK_SIZE); 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci return err; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic int __maybe_unused cbc_encrypt(struct skcipher_request *req) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci struct skcipher_walk walk; 24062306a36Sopenharmony_ci int err; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 24362306a36Sopenharmony_ci if (err) 24462306a36Sopenharmony_ci return err; 24562306a36Sopenharmony_ci return cbc_encrypt_walk(req, &walk); 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_cistatic int cbc_decrypt_walk(struct skcipher_request *req, 24962306a36Sopenharmony_ci struct skcipher_walk *walk) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 25262306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 25362306a36Sopenharmony_ci int err = 0, rounds = 6 + ctx->key_length / 4; 25462306a36Sopenharmony_ci unsigned int blocks; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci while ((blocks = (walk->nbytes / AES_BLOCK_SIZE))) { 25762306a36Sopenharmony_ci kernel_neon_begin(); 25862306a36Sopenharmony_ci aes_cbc_decrypt(walk->dst.virt.addr, walk->src.virt.addr, 25962306a36Sopenharmony_ci ctx->key_dec, rounds, blocks, walk->iv); 26062306a36Sopenharmony_ci kernel_neon_end(); 26162306a36Sopenharmony_ci err = skcipher_walk_done(walk, walk->nbytes % AES_BLOCK_SIZE); 26262306a36Sopenharmony_ci } 26362306a36Sopenharmony_ci return err; 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic int __maybe_unused cbc_decrypt(struct skcipher_request *req) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci struct skcipher_walk walk; 26962306a36Sopenharmony_ci int err; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 27262306a36Sopenharmony_ci if (err) 27362306a36Sopenharmony_ci return err; 27462306a36Sopenharmony_ci return cbc_decrypt_walk(req, &walk); 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic int cts_cbc_encrypt(struct skcipher_request *req) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 28062306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 28162306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 28262306a36Sopenharmony_ci int cbc_blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2; 28362306a36Sopenharmony_ci struct scatterlist *src = req->src, *dst = req->dst; 28462306a36Sopenharmony_ci struct scatterlist sg_src[2], sg_dst[2]; 28562306a36Sopenharmony_ci struct skcipher_request subreq; 28662306a36Sopenharmony_ci struct skcipher_walk walk; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci skcipher_request_set_tfm(&subreq, tfm); 28962306a36Sopenharmony_ci skcipher_request_set_callback(&subreq, skcipher_request_flags(req), 29062306a36Sopenharmony_ci NULL, NULL); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci if (req->cryptlen <= AES_BLOCK_SIZE) { 29362306a36Sopenharmony_ci if (req->cryptlen < AES_BLOCK_SIZE) 29462306a36Sopenharmony_ci return -EINVAL; 29562306a36Sopenharmony_ci cbc_blocks = 1; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci if (cbc_blocks > 0) { 29962306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, req->src, req->dst, 30062306a36Sopenharmony_ci cbc_blocks * AES_BLOCK_SIZE, 30162306a36Sopenharmony_ci req->iv); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false) ?: 30462306a36Sopenharmony_ci cbc_encrypt_walk(&subreq, &walk); 30562306a36Sopenharmony_ci if (err) 30662306a36Sopenharmony_ci return err; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci if (req->cryptlen == AES_BLOCK_SIZE) 30962306a36Sopenharmony_ci return 0; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci dst = src = scatterwalk_ffwd(sg_src, req->src, subreq.cryptlen); 31262306a36Sopenharmony_ci if (req->dst != req->src) 31362306a36Sopenharmony_ci dst = scatterwalk_ffwd(sg_dst, req->dst, 31462306a36Sopenharmony_ci subreq.cryptlen); 31562306a36Sopenharmony_ci } 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* handle ciphertext stealing */ 31862306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, src, dst, 31962306a36Sopenharmony_ci req->cryptlen - cbc_blocks * AES_BLOCK_SIZE, 32062306a36Sopenharmony_ci req->iv); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false); 32362306a36Sopenharmony_ci if (err) 32462306a36Sopenharmony_ci return err; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci kernel_neon_begin(); 32762306a36Sopenharmony_ci aes_cbc_cts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 32862306a36Sopenharmony_ci ctx->key_enc, rounds, walk.nbytes, walk.iv); 32962306a36Sopenharmony_ci kernel_neon_end(); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci return skcipher_walk_done(&walk, 0); 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic int cts_cbc_decrypt(struct skcipher_request *req) 33562306a36Sopenharmony_ci{ 33662306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 33762306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 33862306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 33962306a36Sopenharmony_ci int cbc_blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2; 34062306a36Sopenharmony_ci struct scatterlist *src = req->src, *dst = req->dst; 34162306a36Sopenharmony_ci struct scatterlist sg_src[2], sg_dst[2]; 34262306a36Sopenharmony_ci struct skcipher_request subreq; 34362306a36Sopenharmony_ci struct skcipher_walk walk; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci skcipher_request_set_tfm(&subreq, tfm); 34662306a36Sopenharmony_ci skcipher_request_set_callback(&subreq, skcipher_request_flags(req), 34762306a36Sopenharmony_ci NULL, NULL); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci if (req->cryptlen <= AES_BLOCK_SIZE) { 35062306a36Sopenharmony_ci if (req->cryptlen < AES_BLOCK_SIZE) 35162306a36Sopenharmony_ci return -EINVAL; 35262306a36Sopenharmony_ci cbc_blocks = 1; 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci if (cbc_blocks > 0) { 35662306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, req->src, req->dst, 35762306a36Sopenharmony_ci cbc_blocks * AES_BLOCK_SIZE, 35862306a36Sopenharmony_ci req->iv); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false) ?: 36162306a36Sopenharmony_ci cbc_decrypt_walk(&subreq, &walk); 36262306a36Sopenharmony_ci if (err) 36362306a36Sopenharmony_ci return err; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci if (req->cryptlen == AES_BLOCK_SIZE) 36662306a36Sopenharmony_ci return 0; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci dst = src = scatterwalk_ffwd(sg_src, req->src, subreq.cryptlen); 36962306a36Sopenharmony_ci if (req->dst != req->src) 37062306a36Sopenharmony_ci dst = scatterwalk_ffwd(sg_dst, req->dst, 37162306a36Sopenharmony_ci subreq.cryptlen); 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* handle ciphertext stealing */ 37562306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, src, dst, 37662306a36Sopenharmony_ci req->cryptlen - cbc_blocks * AES_BLOCK_SIZE, 37762306a36Sopenharmony_ci req->iv); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false); 38062306a36Sopenharmony_ci if (err) 38162306a36Sopenharmony_ci return err; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci kernel_neon_begin(); 38462306a36Sopenharmony_ci aes_cbc_cts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 38562306a36Sopenharmony_ci ctx->key_dec, rounds, walk.nbytes, walk.iv); 38662306a36Sopenharmony_ci kernel_neon_end(); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci return skcipher_walk_done(&walk, 0); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic int __maybe_unused essiv_cbc_init_tfm(struct crypto_skcipher *tfm) 39262306a36Sopenharmony_ci{ 39362306a36Sopenharmony_ci struct crypto_aes_essiv_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci ctx->hash = crypto_alloc_shash("sha256", 0, 0); 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci return PTR_ERR_OR_ZERO(ctx->hash); 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_cistatic void __maybe_unused essiv_cbc_exit_tfm(struct crypto_skcipher *tfm) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci struct crypto_aes_essiv_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci crypto_free_shash(ctx->hash); 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic int __maybe_unused essiv_cbc_encrypt(struct skcipher_request *req) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 41062306a36Sopenharmony_ci struct crypto_aes_essiv_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 41162306a36Sopenharmony_ci int err, rounds = 6 + ctx->key1.key_length / 4; 41262306a36Sopenharmony_ci struct skcipher_walk walk; 41362306a36Sopenharmony_ci unsigned int blocks; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci blocks = walk.nbytes / AES_BLOCK_SIZE; 41862306a36Sopenharmony_ci if (blocks) { 41962306a36Sopenharmony_ci kernel_neon_begin(); 42062306a36Sopenharmony_ci aes_essiv_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 42162306a36Sopenharmony_ci ctx->key1.key_enc, rounds, blocks, 42262306a36Sopenharmony_ci req->iv, ctx->key2.key_enc); 42362306a36Sopenharmony_ci kernel_neon_end(); 42462306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE); 42562306a36Sopenharmony_ci } 42662306a36Sopenharmony_ci return err ?: cbc_encrypt_walk(req, &walk); 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic int __maybe_unused essiv_cbc_decrypt(struct skcipher_request *req) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 43262306a36Sopenharmony_ci struct crypto_aes_essiv_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 43362306a36Sopenharmony_ci int err, rounds = 6 + ctx->key1.key_length / 4; 43462306a36Sopenharmony_ci struct skcipher_walk walk; 43562306a36Sopenharmony_ci unsigned int blocks; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci blocks = walk.nbytes / AES_BLOCK_SIZE; 44062306a36Sopenharmony_ci if (blocks) { 44162306a36Sopenharmony_ci kernel_neon_begin(); 44262306a36Sopenharmony_ci aes_essiv_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 44362306a36Sopenharmony_ci ctx->key1.key_dec, rounds, blocks, 44462306a36Sopenharmony_ci req->iv, ctx->key2.key_enc); 44562306a36Sopenharmony_ci kernel_neon_end(); 44662306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE); 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci return err ?: cbc_decrypt_walk(req, &walk); 44962306a36Sopenharmony_ci} 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic int __maybe_unused xctr_encrypt(struct skcipher_request *req) 45262306a36Sopenharmony_ci{ 45362306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 45462306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 45562306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 45662306a36Sopenharmony_ci struct skcipher_walk walk; 45762306a36Sopenharmony_ci unsigned int byte_ctr = 0; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci while (walk.nbytes > 0) { 46262306a36Sopenharmony_ci const u8 *src = walk.src.virt.addr; 46362306a36Sopenharmony_ci unsigned int nbytes = walk.nbytes; 46462306a36Sopenharmony_ci u8 *dst = walk.dst.virt.addr; 46562306a36Sopenharmony_ci u8 buf[AES_BLOCK_SIZE]; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci /* 46862306a36Sopenharmony_ci * If given less than 16 bytes, we must copy the partial block 46962306a36Sopenharmony_ci * into a temporary buffer of 16 bytes to avoid out of bounds 47062306a36Sopenharmony_ci * reads and writes. Furthermore, this code is somewhat unusual 47162306a36Sopenharmony_ci * in that it expects the end of the data to be at the end of 47262306a36Sopenharmony_ci * the temporary buffer, rather than the start of the data at 47362306a36Sopenharmony_ci * the start of the temporary buffer. 47462306a36Sopenharmony_ci */ 47562306a36Sopenharmony_ci if (unlikely(nbytes < AES_BLOCK_SIZE)) 47662306a36Sopenharmony_ci src = dst = memcpy(buf + sizeof(buf) - nbytes, 47762306a36Sopenharmony_ci src, nbytes); 47862306a36Sopenharmony_ci else if (nbytes < walk.total) 47962306a36Sopenharmony_ci nbytes &= ~(AES_BLOCK_SIZE - 1); 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci kernel_neon_begin(); 48262306a36Sopenharmony_ci aes_xctr_encrypt(dst, src, ctx->key_enc, rounds, nbytes, 48362306a36Sopenharmony_ci walk.iv, byte_ctr); 48462306a36Sopenharmony_ci kernel_neon_end(); 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci if (unlikely(nbytes < AES_BLOCK_SIZE)) 48762306a36Sopenharmony_ci memcpy(walk.dst.virt.addr, 48862306a36Sopenharmony_ci buf + sizeof(buf) - nbytes, nbytes); 48962306a36Sopenharmony_ci byte_ctr += nbytes; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes - nbytes); 49262306a36Sopenharmony_ci } 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci return err; 49562306a36Sopenharmony_ci} 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_cistatic int __maybe_unused ctr_encrypt(struct skcipher_request *req) 49862306a36Sopenharmony_ci{ 49962306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 50062306a36Sopenharmony_ci struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); 50162306a36Sopenharmony_ci int err, rounds = 6 + ctx->key_length / 4; 50262306a36Sopenharmony_ci struct skcipher_walk walk; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci while (walk.nbytes > 0) { 50762306a36Sopenharmony_ci const u8 *src = walk.src.virt.addr; 50862306a36Sopenharmony_ci unsigned int nbytes = walk.nbytes; 50962306a36Sopenharmony_ci u8 *dst = walk.dst.virt.addr; 51062306a36Sopenharmony_ci u8 buf[AES_BLOCK_SIZE]; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci /* 51362306a36Sopenharmony_ci * If given less than 16 bytes, we must copy the partial block 51462306a36Sopenharmony_ci * into a temporary buffer of 16 bytes to avoid out of bounds 51562306a36Sopenharmony_ci * reads and writes. Furthermore, this code is somewhat unusual 51662306a36Sopenharmony_ci * in that it expects the end of the data to be at the end of 51762306a36Sopenharmony_ci * the temporary buffer, rather than the start of the data at 51862306a36Sopenharmony_ci * the start of the temporary buffer. 51962306a36Sopenharmony_ci */ 52062306a36Sopenharmony_ci if (unlikely(nbytes < AES_BLOCK_SIZE)) 52162306a36Sopenharmony_ci src = dst = memcpy(buf + sizeof(buf) - nbytes, 52262306a36Sopenharmony_ci src, nbytes); 52362306a36Sopenharmony_ci else if (nbytes < walk.total) 52462306a36Sopenharmony_ci nbytes &= ~(AES_BLOCK_SIZE - 1); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci kernel_neon_begin(); 52762306a36Sopenharmony_ci aes_ctr_encrypt(dst, src, ctx->key_enc, rounds, nbytes, 52862306a36Sopenharmony_ci walk.iv); 52962306a36Sopenharmony_ci kernel_neon_end(); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci if (unlikely(nbytes < AES_BLOCK_SIZE)) 53262306a36Sopenharmony_ci memcpy(walk.dst.virt.addr, 53362306a36Sopenharmony_ci buf + sizeof(buf) - nbytes, nbytes); 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes - nbytes); 53662306a36Sopenharmony_ci } 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return err; 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistatic int __maybe_unused xts_encrypt(struct skcipher_request *req) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 54462306a36Sopenharmony_ci struct crypto_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm); 54562306a36Sopenharmony_ci int err, first, rounds = 6 + ctx->key1.key_length / 4; 54662306a36Sopenharmony_ci int tail = req->cryptlen % AES_BLOCK_SIZE; 54762306a36Sopenharmony_ci struct scatterlist sg_src[2], sg_dst[2]; 54862306a36Sopenharmony_ci struct skcipher_request subreq; 54962306a36Sopenharmony_ci struct scatterlist *src, *dst; 55062306a36Sopenharmony_ci struct skcipher_walk walk; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (req->cryptlen < AES_BLOCK_SIZE) 55362306a36Sopenharmony_ci return -EINVAL; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci if (unlikely(tail > 0 && walk.nbytes < walk.total)) { 55862306a36Sopenharmony_ci int xts_blocks = DIV_ROUND_UP(req->cryptlen, 55962306a36Sopenharmony_ci AES_BLOCK_SIZE) - 2; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci skcipher_walk_abort(&walk); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci skcipher_request_set_tfm(&subreq, tfm); 56462306a36Sopenharmony_ci skcipher_request_set_callback(&subreq, 56562306a36Sopenharmony_ci skcipher_request_flags(req), 56662306a36Sopenharmony_ci NULL, NULL); 56762306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, req->src, req->dst, 56862306a36Sopenharmony_ci xts_blocks * AES_BLOCK_SIZE, 56962306a36Sopenharmony_ci req->iv); 57062306a36Sopenharmony_ci req = &subreq; 57162306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 57262306a36Sopenharmony_ci } else { 57362306a36Sopenharmony_ci tail = 0; 57462306a36Sopenharmony_ci } 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { 57762306a36Sopenharmony_ci int nbytes = walk.nbytes; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci if (walk.nbytes < walk.total) 58062306a36Sopenharmony_ci nbytes &= ~(AES_BLOCK_SIZE - 1); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci kernel_neon_begin(); 58362306a36Sopenharmony_ci aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 58462306a36Sopenharmony_ci ctx->key1.key_enc, rounds, nbytes, 58562306a36Sopenharmony_ci ctx->key2.key_enc, walk.iv, first); 58662306a36Sopenharmony_ci kernel_neon_end(); 58762306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes - nbytes); 58862306a36Sopenharmony_ci } 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci if (err || likely(!tail)) 59162306a36Sopenharmony_ci return err; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); 59462306a36Sopenharmony_ci if (req->dst != req->src) 59562306a36Sopenharmony_ci dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, 59862306a36Sopenharmony_ci req->iv); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false); 60162306a36Sopenharmony_ci if (err) 60262306a36Sopenharmony_ci return err; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci kernel_neon_begin(); 60562306a36Sopenharmony_ci aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 60662306a36Sopenharmony_ci ctx->key1.key_enc, rounds, walk.nbytes, 60762306a36Sopenharmony_ci ctx->key2.key_enc, walk.iv, first); 60862306a36Sopenharmony_ci kernel_neon_end(); 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci return skcipher_walk_done(&walk, 0); 61162306a36Sopenharmony_ci} 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_cistatic int __maybe_unused xts_decrypt(struct skcipher_request *req) 61462306a36Sopenharmony_ci{ 61562306a36Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 61662306a36Sopenharmony_ci struct crypto_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm); 61762306a36Sopenharmony_ci int err, first, rounds = 6 + ctx->key1.key_length / 4; 61862306a36Sopenharmony_ci int tail = req->cryptlen % AES_BLOCK_SIZE; 61962306a36Sopenharmony_ci struct scatterlist sg_src[2], sg_dst[2]; 62062306a36Sopenharmony_ci struct skcipher_request subreq; 62162306a36Sopenharmony_ci struct scatterlist *src, *dst; 62262306a36Sopenharmony_ci struct skcipher_walk walk; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci if (req->cryptlen < AES_BLOCK_SIZE) 62562306a36Sopenharmony_ci return -EINVAL; 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci if (unlikely(tail > 0 && walk.nbytes < walk.total)) { 63062306a36Sopenharmony_ci int xts_blocks = DIV_ROUND_UP(req->cryptlen, 63162306a36Sopenharmony_ci AES_BLOCK_SIZE) - 2; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci skcipher_walk_abort(&walk); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci skcipher_request_set_tfm(&subreq, tfm); 63662306a36Sopenharmony_ci skcipher_request_set_callback(&subreq, 63762306a36Sopenharmony_ci skcipher_request_flags(req), 63862306a36Sopenharmony_ci NULL, NULL); 63962306a36Sopenharmony_ci skcipher_request_set_crypt(&subreq, req->src, req->dst, 64062306a36Sopenharmony_ci xts_blocks * AES_BLOCK_SIZE, 64162306a36Sopenharmony_ci req->iv); 64262306a36Sopenharmony_ci req = &subreq; 64362306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 64462306a36Sopenharmony_ci } else { 64562306a36Sopenharmony_ci tail = 0; 64662306a36Sopenharmony_ci } 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci for (first = 1; walk.nbytes >= AES_BLOCK_SIZE; first = 0) { 64962306a36Sopenharmony_ci int nbytes = walk.nbytes; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci if (walk.nbytes < walk.total) 65262306a36Sopenharmony_ci nbytes &= ~(AES_BLOCK_SIZE - 1); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci kernel_neon_begin(); 65562306a36Sopenharmony_ci aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 65662306a36Sopenharmony_ci ctx->key1.key_dec, rounds, nbytes, 65762306a36Sopenharmony_ci ctx->key2.key_enc, walk.iv, first); 65862306a36Sopenharmony_ci kernel_neon_end(); 65962306a36Sopenharmony_ci err = skcipher_walk_done(&walk, walk.nbytes - nbytes); 66062306a36Sopenharmony_ci } 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci if (err || likely(!tail)) 66362306a36Sopenharmony_ci return err; 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); 66662306a36Sopenharmony_ci if (req->dst != req->src) 66762306a36Sopenharmony_ci dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, 67062306a36Sopenharmony_ci req->iv); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci err = skcipher_walk_virt(&walk, &subreq, false); 67362306a36Sopenharmony_ci if (err) 67462306a36Sopenharmony_ci return err; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci kernel_neon_begin(); 67862306a36Sopenharmony_ci aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 67962306a36Sopenharmony_ci ctx->key1.key_dec, rounds, walk.nbytes, 68062306a36Sopenharmony_ci ctx->key2.key_enc, walk.iv, first); 68162306a36Sopenharmony_ci kernel_neon_end(); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci return skcipher_walk_done(&walk, 0); 68462306a36Sopenharmony_ci} 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_cistatic struct skcipher_alg aes_algs[] = { { 68762306a36Sopenharmony_ci#if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS) 68862306a36Sopenharmony_ci .base = { 68962306a36Sopenharmony_ci .cra_name = "ecb(aes)", 69062306a36Sopenharmony_ci .cra_driver_name = "ecb-aes-" MODE, 69162306a36Sopenharmony_ci .cra_priority = PRIO, 69262306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 69362306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_ctx), 69462306a36Sopenharmony_ci .cra_module = THIS_MODULE, 69562306a36Sopenharmony_ci }, 69662306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 69762306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 69862306a36Sopenharmony_ci .setkey = skcipher_aes_setkey, 69962306a36Sopenharmony_ci .encrypt = ecb_encrypt, 70062306a36Sopenharmony_ci .decrypt = ecb_decrypt, 70162306a36Sopenharmony_ci}, { 70262306a36Sopenharmony_ci .base = { 70362306a36Sopenharmony_ci .cra_name = "cbc(aes)", 70462306a36Sopenharmony_ci .cra_driver_name = "cbc-aes-" MODE, 70562306a36Sopenharmony_ci .cra_priority = PRIO, 70662306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 70762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_ctx), 70862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 70962306a36Sopenharmony_ci }, 71062306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 71162306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 71262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 71362306a36Sopenharmony_ci .setkey = skcipher_aes_setkey, 71462306a36Sopenharmony_ci .encrypt = cbc_encrypt, 71562306a36Sopenharmony_ci .decrypt = cbc_decrypt, 71662306a36Sopenharmony_ci}, { 71762306a36Sopenharmony_ci .base = { 71862306a36Sopenharmony_ci .cra_name = "ctr(aes)", 71962306a36Sopenharmony_ci .cra_driver_name = "ctr-aes-" MODE, 72062306a36Sopenharmony_ci .cra_priority = PRIO, 72162306a36Sopenharmony_ci .cra_blocksize = 1, 72262306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_ctx), 72362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 72462306a36Sopenharmony_ci }, 72562306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 72662306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 72762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 72862306a36Sopenharmony_ci .chunksize = AES_BLOCK_SIZE, 72962306a36Sopenharmony_ci .setkey = skcipher_aes_setkey, 73062306a36Sopenharmony_ci .encrypt = ctr_encrypt, 73162306a36Sopenharmony_ci .decrypt = ctr_encrypt, 73262306a36Sopenharmony_ci}, { 73362306a36Sopenharmony_ci .base = { 73462306a36Sopenharmony_ci .cra_name = "xctr(aes)", 73562306a36Sopenharmony_ci .cra_driver_name = "xctr-aes-" MODE, 73662306a36Sopenharmony_ci .cra_priority = PRIO, 73762306a36Sopenharmony_ci .cra_blocksize = 1, 73862306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_ctx), 73962306a36Sopenharmony_ci .cra_module = THIS_MODULE, 74062306a36Sopenharmony_ci }, 74162306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 74262306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 74362306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 74462306a36Sopenharmony_ci .chunksize = AES_BLOCK_SIZE, 74562306a36Sopenharmony_ci .setkey = skcipher_aes_setkey, 74662306a36Sopenharmony_ci .encrypt = xctr_encrypt, 74762306a36Sopenharmony_ci .decrypt = xctr_encrypt, 74862306a36Sopenharmony_ci}, { 74962306a36Sopenharmony_ci .base = { 75062306a36Sopenharmony_ci .cra_name = "xts(aes)", 75162306a36Sopenharmony_ci .cra_driver_name = "xts-aes-" MODE, 75262306a36Sopenharmony_ci .cra_priority = PRIO, 75362306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 75462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_xts_ctx), 75562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 75662306a36Sopenharmony_ci }, 75762306a36Sopenharmony_ci .min_keysize = 2 * AES_MIN_KEY_SIZE, 75862306a36Sopenharmony_ci .max_keysize = 2 * AES_MAX_KEY_SIZE, 75962306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 76062306a36Sopenharmony_ci .walksize = 2 * AES_BLOCK_SIZE, 76162306a36Sopenharmony_ci .setkey = xts_set_key, 76262306a36Sopenharmony_ci .encrypt = xts_encrypt, 76362306a36Sopenharmony_ci .decrypt = xts_decrypt, 76462306a36Sopenharmony_ci}, { 76562306a36Sopenharmony_ci#endif 76662306a36Sopenharmony_ci .base = { 76762306a36Sopenharmony_ci .cra_name = "cts(cbc(aes))", 76862306a36Sopenharmony_ci .cra_driver_name = "cts-cbc-aes-" MODE, 76962306a36Sopenharmony_ci .cra_priority = PRIO, 77062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 77162306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_ctx), 77262306a36Sopenharmony_ci .cra_module = THIS_MODULE, 77362306a36Sopenharmony_ci }, 77462306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 77562306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 77662306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 77762306a36Sopenharmony_ci .walksize = 2 * AES_BLOCK_SIZE, 77862306a36Sopenharmony_ci .setkey = skcipher_aes_setkey, 77962306a36Sopenharmony_ci .encrypt = cts_cbc_encrypt, 78062306a36Sopenharmony_ci .decrypt = cts_cbc_decrypt, 78162306a36Sopenharmony_ci}, { 78262306a36Sopenharmony_ci .base = { 78362306a36Sopenharmony_ci .cra_name = "essiv(cbc(aes),sha256)", 78462306a36Sopenharmony_ci .cra_driver_name = "essiv-cbc-aes-sha256-" MODE, 78562306a36Sopenharmony_ci .cra_priority = PRIO + 1, 78662306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 78762306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct crypto_aes_essiv_cbc_ctx), 78862306a36Sopenharmony_ci .cra_module = THIS_MODULE, 78962306a36Sopenharmony_ci }, 79062306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 79162306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 79262306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 79362306a36Sopenharmony_ci .setkey = essiv_cbc_set_key, 79462306a36Sopenharmony_ci .encrypt = essiv_cbc_encrypt, 79562306a36Sopenharmony_ci .decrypt = essiv_cbc_decrypt, 79662306a36Sopenharmony_ci .init = essiv_cbc_init_tfm, 79762306a36Sopenharmony_ci .exit = essiv_cbc_exit_tfm, 79862306a36Sopenharmony_ci} }; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_cistatic int cbcmac_setkey(struct crypto_shash *tfm, const u8 *in_key, 80162306a36Sopenharmony_ci unsigned int key_len) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci struct mac_tfm_ctx *ctx = crypto_shash_ctx(tfm); 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci return aes_expandkey(&ctx->key, in_key, key_len); 80662306a36Sopenharmony_ci} 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_cistatic void cmac_gf128_mul_by_x(be128 *y, const be128 *x) 80962306a36Sopenharmony_ci{ 81062306a36Sopenharmony_ci u64 a = be64_to_cpu(x->a); 81162306a36Sopenharmony_ci u64 b = be64_to_cpu(x->b); 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci y->a = cpu_to_be64((a << 1) | (b >> 63)); 81462306a36Sopenharmony_ci y->b = cpu_to_be64((b << 1) ^ ((a >> 63) ? 0x87 : 0)); 81562306a36Sopenharmony_ci} 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_cistatic int cmac_setkey(struct crypto_shash *tfm, const u8 *in_key, 81862306a36Sopenharmony_ci unsigned int key_len) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci struct mac_tfm_ctx *ctx = crypto_shash_ctx(tfm); 82162306a36Sopenharmony_ci be128 *consts = (be128 *)ctx->consts; 82262306a36Sopenharmony_ci int rounds = 6 + key_len / 4; 82362306a36Sopenharmony_ci int err; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci err = cbcmac_setkey(tfm, in_key, key_len); 82662306a36Sopenharmony_ci if (err) 82762306a36Sopenharmony_ci return err; 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_ci /* encrypt the zero vector */ 83062306a36Sopenharmony_ci kernel_neon_begin(); 83162306a36Sopenharmony_ci aes_ecb_encrypt(ctx->consts, (u8[AES_BLOCK_SIZE]){}, ctx->key.key_enc, 83262306a36Sopenharmony_ci rounds, 1); 83362306a36Sopenharmony_ci kernel_neon_end(); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci cmac_gf128_mul_by_x(consts, consts); 83662306a36Sopenharmony_ci cmac_gf128_mul_by_x(consts + 1, consts); 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci return 0; 83962306a36Sopenharmony_ci} 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_cistatic int xcbc_setkey(struct crypto_shash *tfm, const u8 *in_key, 84262306a36Sopenharmony_ci unsigned int key_len) 84362306a36Sopenharmony_ci{ 84462306a36Sopenharmony_ci static u8 const ks[3][AES_BLOCK_SIZE] = { 84562306a36Sopenharmony_ci { [0 ... AES_BLOCK_SIZE - 1] = 0x1 }, 84662306a36Sopenharmony_ci { [0 ... AES_BLOCK_SIZE - 1] = 0x2 }, 84762306a36Sopenharmony_ci { [0 ... AES_BLOCK_SIZE - 1] = 0x3 }, 84862306a36Sopenharmony_ci }; 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci struct mac_tfm_ctx *ctx = crypto_shash_ctx(tfm); 85162306a36Sopenharmony_ci int rounds = 6 + key_len / 4; 85262306a36Sopenharmony_ci u8 key[AES_BLOCK_SIZE]; 85362306a36Sopenharmony_ci int err; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci err = cbcmac_setkey(tfm, in_key, key_len); 85662306a36Sopenharmony_ci if (err) 85762306a36Sopenharmony_ci return err; 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci kernel_neon_begin(); 86062306a36Sopenharmony_ci aes_ecb_encrypt(key, ks[0], ctx->key.key_enc, rounds, 1); 86162306a36Sopenharmony_ci aes_ecb_encrypt(ctx->consts, ks[1], ctx->key.key_enc, rounds, 2); 86262306a36Sopenharmony_ci kernel_neon_end(); 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci return cbcmac_setkey(tfm, key, sizeof(key)); 86562306a36Sopenharmony_ci} 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_cistatic int mac_init(struct shash_desc *desc) 86862306a36Sopenharmony_ci{ 86962306a36Sopenharmony_ci struct mac_desc_ctx *ctx = shash_desc_ctx(desc); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci memset(ctx->dg, 0, AES_BLOCK_SIZE); 87262306a36Sopenharmony_ci ctx->len = 0; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci return 0; 87562306a36Sopenharmony_ci} 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_cistatic void mac_do_update(struct crypto_aes_ctx *ctx, u8 const in[], int blocks, 87862306a36Sopenharmony_ci u8 dg[], int enc_before, int enc_after) 87962306a36Sopenharmony_ci{ 88062306a36Sopenharmony_ci int rounds = 6 + ctx->key_length / 4; 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci if (crypto_simd_usable()) { 88362306a36Sopenharmony_ci int rem; 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci do { 88662306a36Sopenharmony_ci kernel_neon_begin(); 88762306a36Sopenharmony_ci rem = aes_mac_update(in, ctx->key_enc, rounds, blocks, 88862306a36Sopenharmony_ci dg, enc_before, enc_after); 88962306a36Sopenharmony_ci kernel_neon_end(); 89062306a36Sopenharmony_ci in += (blocks - rem) * AES_BLOCK_SIZE; 89162306a36Sopenharmony_ci blocks = rem; 89262306a36Sopenharmony_ci enc_before = 0; 89362306a36Sopenharmony_ci } while (blocks); 89462306a36Sopenharmony_ci } else { 89562306a36Sopenharmony_ci if (enc_before) 89662306a36Sopenharmony_ci aes_encrypt(ctx, dg, dg); 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci while (blocks--) { 89962306a36Sopenharmony_ci crypto_xor(dg, in, AES_BLOCK_SIZE); 90062306a36Sopenharmony_ci in += AES_BLOCK_SIZE; 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci if (blocks || enc_after) 90362306a36Sopenharmony_ci aes_encrypt(ctx, dg, dg); 90462306a36Sopenharmony_ci } 90562306a36Sopenharmony_ci } 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistatic int mac_update(struct shash_desc *desc, const u8 *p, unsigned int len) 90962306a36Sopenharmony_ci{ 91062306a36Sopenharmony_ci struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 91162306a36Sopenharmony_ci struct mac_desc_ctx *ctx = shash_desc_ctx(desc); 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci while (len > 0) { 91462306a36Sopenharmony_ci unsigned int l; 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci if ((ctx->len % AES_BLOCK_SIZE) == 0 && 91762306a36Sopenharmony_ci (ctx->len + len) > AES_BLOCK_SIZE) { 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci int blocks = len / AES_BLOCK_SIZE; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci len %= AES_BLOCK_SIZE; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci mac_do_update(&tctx->key, p, blocks, ctx->dg, 92462306a36Sopenharmony_ci (ctx->len != 0), (len != 0)); 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci p += blocks * AES_BLOCK_SIZE; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci if (!len) { 92962306a36Sopenharmony_ci ctx->len = AES_BLOCK_SIZE; 93062306a36Sopenharmony_ci break; 93162306a36Sopenharmony_ci } 93262306a36Sopenharmony_ci ctx->len = 0; 93362306a36Sopenharmony_ci } 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci l = min(len, AES_BLOCK_SIZE - ctx->len); 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci if (l <= AES_BLOCK_SIZE) { 93862306a36Sopenharmony_ci crypto_xor(ctx->dg + ctx->len, p, l); 93962306a36Sopenharmony_ci ctx->len += l; 94062306a36Sopenharmony_ci len -= l; 94162306a36Sopenharmony_ci p += l; 94262306a36Sopenharmony_ci } 94362306a36Sopenharmony_ci } 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci return 0; 94662306a36Sopenharmony_ci} 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_cistatic int cbcmac_final(struct shash_desc *desc, u8 *out) 94962306a36Sopenharmony_ci{ 95062306a36Sopenharmony_ci struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 95162306a36Sopenharmony_ci struct mac_desc_ctx *ctx = shash_desc_ctx(desc); 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci mac_do_update(&tctx->key, NULL, 0, ctx->dg, (ctx->len != 0), 0); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci memcpy(out, ctx->dg, AES_BLOCK_SIZE); 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci return 0; 95862306a36Sopenharmony_ci} 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_cistatic int cmac_final(struct shash_desc *desc, u8 *out) 96162306a36Sopenharmony_ci{ 96262306a36Sopenharmony_ci struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 96362306a36Sopenharmony_ci struct mac_desc_ctx *ctx = shash_desc_ctx(desc); 96462306a36Sopenharmony_ci u8 *consts = tctx->consts; 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci if (ctx->len != AES_BLOCK_SIZE) { 96762306a36Sopenharmony_ci ctx->dg[ctx->len] ^= 0x80; 96862306a36Sopenharmony_ci consts += AES_BLOCK_SIZE; 96962306a36Sopenharmony_ci } 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci mac_do_update(&tctx->key, consts, 1, ctx->dg, 0, 1); 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci memcpy(out, ctx->dg, AES_BLOCK_SIZE); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci return 0; 97662306a36Sopenharmony_ci} 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_cistatic struct shash_alg mac_algs[] = { { 97962306a36Sopenharmony_ci .base.cra_name = "cmac(aes)", 98062306a36Sopenharmony_ci .base.cra_driver_name = "cmac-aes-" MODE, 98162306a36Sopenharmony_ci .base.cra_priority = PRIO, 98262306a36Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 98362306a36Sopenharmony_ci .base.cra_ctxsize = sizeof(struct mac_tfm_ctx) + 98462306a36Sopenharmony_ci 2 * AES_BLOCK_SIZE, 98562306a36Sopenharmony_ci .base.cra_module = THIS_MODULE, 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci .digestsize = AES_BLOCK_SIZE, 98862306a36Sopenharmony_ci .init = mac_init, 98962306a36Sopenharmony_ci .update = mac_update, 99062306a36Sopenharmony_ci .final = cmac_final, 99162306a36Sopenharmony_ci .setkey = cmac_setkey, 99262306a36Sopenharmony_ci .descsize = sizeof(struct mac_desc_ctx), 99362306a36Sopenharmony_ci}, { 99462306a36Sopenharmony_ci .base.cra_name = "xcbc(aes)", 99562306a36Sopenharmony_ci .base.cra_driver_name = "xcbc-aes-" MODE, 99662306a36Sopenharmony_ci .base.cra_priority = PRIO, 99762306a36Sopenharmony_ci .base.cra_blocksize = AES_BLOCK_SIZE, 99862306a36Sopenharmony_ci .base.cra_ctxsize = sizeof(struct mac_tfm_ctx) + 99962306a36Sopenharmony_ci 2 * AES_BLOCK_SIZE, 100062306a36Sopenharmony_ci .base.cra_module = THIS_MODULE, 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci .digestsize = AES_BLOCK_SIZE, 100362306a36Sopenharmony_ci .init = mac_init, 100462306a36Sopenharmony_ci .update = mac_update, 100562306a36Sopenharmony_ci .final = cmac_final, 100662306a36Sopenharmony_ci .setkey = xcbc_setkey, 100762306a36Sopenharmony_ci .descsize = sizeof(struct mac_desc_ctx), 100862306a36Sopenharmony_ci}, { 100962306a36Sopenharmony_ci .base.cra_name = "cbcmac(aes)", 101062306a36Sopenharmony_ci .base.cra_driver_name = "cbcmac-aes-" MODE, 101162306a36Sopenharmony_ci .base.cra_priority = PRIO, 101262306a36Sopenharmony_ci .base.cra_blocksize = 1, 101362306a36Sopenharmony_ci .base.cra_ctxsize = sizeof(struct mac_tfm_ctx), 101462306a36Sopenharmony_ci .base.cra_module = THIS_MODULE, 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci .digestsize = AES_BLOCK_SIZE, 101762306a36Sopenharmony_ci .init = mac_init, 101862306a36Sopenharmony_ci .update = mac_update, 101962306a36Sopenharmony_ci .final = cbcmac_final, 102062306a36Sopenharmony_ci .setkey = cbcmac_setkey, 102162306a36Sopenharmony_ci .descsize = sizeof(struct mac_desc_ctx), 102262306a36Sopenharmony_ci} }; 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_cistatic void aes_exit(void) 102562306a36Sopenharmony_ci{ 102662306a36Sopenharmony_ci crypto_unregister_shashes(mac_algs, ARRAY_SIZE(mac_algs)); 102762306a36Sopenharmony_ci crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); 102862306a36Sopenharmony_ci} 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_cistatic int __init aes_init(void) 103162306a36Sopenharmony_ci{ 103262306a36Sopenharmony_ci int err; 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); 103562306a36Sopenharmony_ci if (err) 103662306a36Sopenharmony_ci return err; 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci err = crypto_register_shashes(mac_algs, ARRAY_SIZE(mac_algs)); 103962306a36Sopenharmony_ci if (err) 104062306a36Sopenharmony_ci goto unregister_ciphers; 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci return 0; 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ciunregister_ciphers: 104562306a36Sopenharmony_ci crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); 104662306a36Sopenharmony_ci return err; 104762306a36Sopenharmony_ci} 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci#ifdef USE_V8_CRYPTO_EXTENSIONS 105062306a36Sopenharmony_cimodule_cpu_feature_match(AES, aes_init); 105162306a36Sopenharmony_ci#else 105262306a36Sopenharmony_cimodule_init(aes_init); 105362306a36Sopenharmony_ciEXPORT_SYMBOL(neon_aes_ecb_encrypt); 105462306a36Sopenharmony_ciEXPORT_SYMBOL(neon_aes_cbc_encrypt); 105562306a36Sopenharmony_ciEXPORT_SYMBOL(neon_aes_ctr_encrypt); 105662306a36Sopenharmony_ciEXPORT_SYMBOL(neon_aes_xts_encrypt); 105762306a36Sopenharmony_ciEXPORT_SYMBOL(neon_aes_xts_decrypt); 105862306a36Sopenharmony_ci#endif 105962306a36Sopenharmony_cimodule_exit(aes_exit); 1060