1*1abee99eSArd Biesheuvel /* 2*1abee99eSArd Biesheuvel * Bit sliced AES using NEON instructions 3*1abee99eSArd Biesheuvel * 4*1abee99eSArd Biesheuvel * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org> 5*1abee99eSArd Biesheuvel * 6*1abee99eSArd Biesheuvel * This program is free software; you can redistribute it and/or modify 7*1abee99eSArd Biesheuvel * it under the terms of the GNU General Public License version 2 as 8*1abee99eSArd Biesheuvel * published by the Free Software Foundation. 9*1abee99eSArd Biesheuvel */ 10*1abee99eSArd Biesheuvel 11*1abee99eSArd Biesheuvel #include <asm/neon.h> 12*1abee99eSArd Biesheuvel #include <crypto/aes.h> 13*1abee99eSArd Biesheuvel #include <crypto/cbc.h> 14*1abee99eSArd Biesheuvel #include <crypto/internal/simd.h> 15*1abee99eSArd Biesheuvel #include <crypto/internal/skcipher.h> 16*1abee99eSArd Biesheuvel #include <crypto/xts.h> 17*1abee99eSArd Biesheuvel #include <linux/module.h> 18*1abee99eSArd Biesheuvel 19*1abee99eSArd Biesheuvel MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); 20*1abee99eSArd Biesheuvel MODULE_LICENSE("GPL v2"); 21*1abee99eSArd Biesheuvel 22*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("ecb(aes)"); 23*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("cbc(aes)"); 24*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("ctr(aes)"); 25*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("xts(aes)"); 26*1abee99eSArd Biesheuvel 27*1abee99eSArd Biesheuvel asmlinkage void aesbs_convert_key(u8 out[], u32 const rk[], int rounds); 28*1abee99eSArd Biesheuvel 29*1abee99eSArd Biesheuvel asmlinkage void aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], 30*1abee99eSArd Biesheuvel int rounds, int blocks); 31*1abee99eSArd Biesheuvel asmlinkage void aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], 32*1abee99eSArd Biesheuvel int rounds, int blocks); 33*1abee99eSArd Biesheuvel 34*1abee99eSArd Biesheuvel asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], 35*1abee99eSArd Biesheuvel int rounds, int blocks, u8 iv[]); 36*1abee99eSArd Biesheuvel 37*1abee99eSArd Biesheuvel asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], 38*1abee99eSArd Biesheuvel int rounds, int blocks, u8 iv[], bool final); 39*1abee99eSArd Biesheuvel 40*1abee99eSArd Biesheuvel asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], 41*1abee99eSArd Biesheuvel int rounds, int blocks, u8 iv[]); 42*1abee99eSArd Biesheuvel asmlinkage void aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], 43*1abee99eSArd Biesheuvel int rounds, int blocks, u8 iv[]); 44*1abee99eSArd Biesheuvel 45*1abee99eSArd Biesheuvel asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); 46*1abee99eSArd Biesheuvel 47*1abee99eSArd Biesheuvel struct aesbs_ctx { 48*1abee99eSArd Biesheuvel u8 rk[13 * (8 * AES_BLOCK_SIZE) + 32]; 49*1abee99eSArd Biesheuvel int rounds; 50*1abee99eSArd Biesheuvel } __aligned(AES_BLOCK_SIZE); 51*1abee99eSArd Biesheuvel 52*1abee99eSArd Biesheuvel struct aesbs_cbc_ctx { 53*1abee99eSArd Biesheuvel struct aesbs_ctx key; 54*1abee99eSArd Biesheuvel u32 enc[AES_MAX_KEYLENGTH_U32]; 55*1abee99eSArd Biesheuvel }; 56*1abee99eSArd Biesheuvel 57*1abee99eSArd Biesheuvel struct aesbs_xts_ctx { 58*1abee99eSArd Biesheuvel struct aesbs_ctx key; 59*1abee99eSArd Biesheuvel u32 twkey[AES_MAX_KEYLENGTH_U32]; 60*1abee99eSArd Biesheuvel }; 61*1abee99eSArd Biesheuvel 62*1abee99eSArd Biesheuvel static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key, 63*1abee99eSArd Biesheuvel unsigned int key_len) 64*1abee99eSArd Biesheuvel { 65*1abee99eSArd Biesheuvel struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm); 66*1abee99eSArd Biesheuvel struct crypto_aes_ctx rk; 67*1abee99eSArd Biesheuvel int err; 68*1abee99eSArd Biesheuvel 69*1abee99eSArd Biesheuvel err = crypto_aes_expand_key(&rk, in_key, key_len); 70*1abee99eSArd Biesheuvel if (err) 71*1abee99eSArd Biesheuvel return err; 72*1abee99eSArd Biesheuvel 73*1abee99eSArd Biesheuvel ctx->rounds = 6 + key_len / 4; 74*1abee99eSArd Biesheuvel 75*1abee99eSArd Biesheuvel kernel_neon_begin(); 76*1abee99eSArd Biesheuvel aesbs_convert_key(ctx->rk, rk.key_enc, ctx->rounds); 77*1abee99eSArd Biesheuvel kernel_neon_end(); 78*1abee99eSArd Biesheuvel 79*1abee99eSArd Biesheuvel return 0; 80*1abee99eSArd Biesheuvel } 81*1abee99eSArd Biesheuvel 82*1abee99eSArd Biesheuvel static int __ecb_crypt(struct skcipher_request *req, 83*1abee99eSArd Biesheuvel void (*fn)(u8 out[], u8 const in[], u8 const rk[], 84*1abee99eSArd Biesheuvel int rounds, int blocks)) 85*1abee99eSArd Biesheuvel { 86*1abee99eSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 87*1abee99eSArd Biesheuvel struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm); 88*1abee99eSArd Biesheuvel struct skcipher_walk walk; 89*1abee99eSArd Biesheuvel int err; 90*1abee99eSArd Biesheuvel 91*1abee99eSArd Biesheuvel err = skcipher_walk_virt(&walk, req, true); 92*1abee99eSArd Biesheuvel 93*1abee99eSArd Biesheuvel kernel_neon_begin(); 94*1abee99eSArd Biesheuvel while (walk.nbytes >= AES_BLOCK_SIZE) { 95*1abee99eSArd Biesheuvel unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE; 96*1abee99eSArd Biesheuvel 97*1abee99eSArd Biesheuvel if (walk.nbytes < walk.total) 98*1abee99eSArd Biesheuvel blocks = round_down(blocks, 99*1abee99eSArd Biesheuvel walk.stride / AES_BLOCK_SIZE); 100*1abee99eSArd Biesheuvel 101*1abee99eSArd Biesheuvel fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->rk, 102*1abee99eSArd Biesheuvel ctx->rounds, blocks); 103*1abee99eSArd Biesheuvel err = skcipher_walk_done(&walk, 104*1abee99eSArd Biesheuvel walk.nbytes - blocks * AES_BLOCK_SIZE); 105*1abee99eSArd Biesheuvel } 106*1abee99eSArd Biesheuvel kernel_neon_end(); 107*1abee99eSArd Biesheuvel 108*1abee99eSArd Biesheuvel return err; 109*1abee99eSArd Biesheuvel } 110*1abee99eSArd Biesheuvel 111*1abee99eSArd Biesheuvel static int ecb_encrypt(struct skcipher_request *req) 112*1abee99eSArd Biesheuvel { 113*1abee99eSArd Biesheuvel return __ecb_crypt(req, aesbs_ecb_encrypt); 114*1abee99eSArd Biesheuvel } 115*1abee99eSArd Biesheuvel 116*1abee99eSArd Biesheuvel static int ecb_decrypt(struct skcipher_request *req) 117*1abee99eSArd Biesheuvel { 118*1abee99eSArd Biesheuvel return __ecb_crypt(req, aesbs_ecb_decrypt); 119*1abee99eSArd Biesheuvel } 120*1abee99eSArd Biesheuvel 121*1abee99eSArd Biesheuvel static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key, 122*1abee99eSArd Biesheuvel unsigned int key_len) 123*1abee99eSArd Biesheuvel { 124*1abee99eSArd Biesheuvel struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 125*1abee99eSArd Biesheuvel struct crypto_aes_ctx rk; 126*1abee99eSArd Biesheuvel int err; 127*1abee99eSArd Biesheuvel 128*1abee99eSArd Biesheuvel err = crypto_aes_expand_key(&rk, in_key, key_len); 129*1abee99eSArd Biesheuvel if (err) 130*1abee99eSArd Biesheuvel return err; 131*1abee99eSArd Biesheuvel 132*1abee99eSArd Biesheuvel ctx->key.rounds = 6 + key_len / 4; 133*1abee99eSArd Biesheuvel 134*1abee99eSArd Biesheuvel memcpy(ctx->enc, rk.key_enc, sizeof(ctx->enc)); 135*1abee99eSArd Biesheuvel 136*1abee99eSArd Biesheuvel kernel_neon_begin(); 137*1abee99eSArd Biesheuvel aesbs_convert_key(ctx->key.rk, rk.key_enc, ctx->key.rounds); 138*1abee99eSArd Biesheuvel kernel_neon_end(); 139*1abee99eSArd Biesheuvel 140*1abee99eSArd Biesheuvel return 0; 141*1abee99eSArd Biesheuvel } 142*1abee99eSArd Biesheuvel 143*1abee99eSArd Biesheuvel static void cbc_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst) 144*1abee99eSArd Biesheuvel { 145*1abee99eSArd Biesheuvel struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 146*1abee99eSArd Biesheuvel 147*1abee99eSArd Biesheuvel __aes_arm64_encrypt(ctx->enc, dst, src, ctx->key.rounds); 148*1abee99eSArd Biesheuvel } 149*1abee99eSArd Biesheuvel 150*1abee99eSArd Biesheuvel static int cbc_encrypt(struct skcipher_request *req) 151*1abee99eSArd Biesheuvel { 152*1abee99eSArd Biesheuvel return crypto_cbc_encrypt_walk(req, cbc_encrypt_one); 153*1abee99eSArd Biesheuvel } 154*1abee99eSArd Biesheuvel 155*1abee99eSArd Biesheuvel static int cbc_decrypt(struct skcipher_request *req) 156*1abee99eSArd Biesheuvel { 157*1abee99eSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 158*1abee99eSArd Biesheuvel struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); 159*1abee99eSArd Biesheuvel struct skcipher_walk walk; 160*1abee99eSArd Biesheuvel int err; 161*1abee99eSArd Biesheuvel 162*1abee99eSArd Biesheuvel err = skcipher_walk_virt(&walk, req, true); 163*1abee99eSArd Biesheuvel 164*1abee99eSArd Biesheuvel kernel_neon_begin(); 165*1abee99eSArd Biesheuvel while (walk.nbytes >= AES_BLOCK_SIZE) { 166*1abee99eSArd Biesheuvel unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE; 167*1abee99eSArd Biesheuvel 168*1abee99eSArd Biesheuvel if (walk.nbytes < walk.total) 169*1abee99eSArd Biesheuvel blocks = round_down(blocks, 170*1abee99eSArd Biesheuvel walk.stride / AES_BLOCK_SIZE); 171*1abee99eSArd Biesheuvel 172*1abee99eSArd Biesheuvel aesbs_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr, 173*1abee99eSArd Biesheuvel ctx->key.rk, ctx->key.rounds, blocks, 174*1abee99eSArd Biesheuvel walk.iv); 175*1abee99eSArd Biesheuvel err = skcipher_walk_done(&walk, 176*1abee99eSArd Biesheuvel walk.nbytes - blocks * AES_BLOCK_SIZE); 177*1abee99eSArd Biesheuvel } 178*1abee99eSArd Biesheuvel kernel_neon_end(); 179*1abee99eSArd Biesheuvel 180*1abee99eSArd Biesheuvel return err; 181*1abee99eSArd Biesheuvel } 182*1abee99eSArd Biesheuvel 183*1abee99eSArd Biesheuvel static int ctr_encrypt(struct skcipher_request *req) 184*1abee99eSArd Biesheuvel { 185*1abee99eSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 186*1abee99eSArd Biesheuvel struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm); 187*1abee99eSArd Biesheuvel struct skcipher_walk walk; 188*1abee99eSArd Biesheuvel int err; 189*1abee99eSArd Biesheuvel 190*1abee99eSArd Biesheuvel err = skcipher_walk_virt(&walk, req, true); 191*1abee99eSArd Biesheuvel 192*1abee99eSArd Biesheuvel kernel_neon_begin(); 193*1abee99eSArd Biesheuvel while (walk.nbytes > 0) { 194*1abee99eSArd Biesheuvel unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE; 195*1abee99eSArd Biesheuvel bool final = (walk.total % AES_BLOCK_SIZE) != 0; 196*1abee99eSArd Biesheuvel 197*1abee99eSArd Biesheuvel if (walk.nbytes < walk.total) { 198*1abee99eSArd Biesheuvel blocks = round_down(blocks, 199*1abee99eSArd Biesheuvel walk.stride / AES_BLOCK_SIZE); 200*1abee99eSArd Biesheuvel final = false; 201*1abee99eSArd Biesheuvel } 202*1abee99eSArd Biesheuvel 203*1abee99eSArd Biesheuvel aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr, 204*1abee99eSArd Biesheuvel ctx->rk, ctx->rounds, blocks, walk.iv, final); 205*1abee99eSArd Biesheuvel 206*1abee99eSArd Biesheuvel if (final) { 207*1abee99eSArd Biesheuvel u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; 208*1abee99eSArd Biesheuvel u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; 209*1abee99eSArd Biesheuvel 210*1abee99eSArd Biesheuvel if (dst != src) 211*1abee99eSArd Biesheuvel memcpy(dst, src, walk.total % AES_BLOCK_SIZE); 212*1abee99eSArd Biesheuvel crypto_xor(dst, walk.iv, walk.total % AES_BLOCK_SIZE); 213*1abee99eSArd Biesheuvel 214*1abee99eSArd Biesheuvel err = skcipher_walk_done(&walk, 0); 215*1abee99eSArd Biesheuvel break; 216*1abee99eSArd Biesheuvel } 217*1abee99eSArd Biesheuvel err = skcipher_walk_done(&walk, 218*1abee99eSArd Biesheuvel walk.nbytes - blocks * AES_BLOCK_SIZE); 219*1abee99eSArd Biesheuvel } 220*1abee99eSArd Biesheuvel kernel_neon_end(); 221*1abee99eSArd Biesheuvel 222*1abee99eSArd Biesheuvel return err; 223*1abee99eSArd Biesheuvel } 224*1abee99eSArd Biesheuvel 225*1abee99eSArd Biesheuvel static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, 226*1abee99eSArd Biesheuvel unsigned int key_len) 227*1abee99eSArd Biesheuvel { 228*1abee99eSArd Biesheuvel struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); 229*1abee99eSArd Biesheuvel struct crypto_aes_ctx rk; 230*1abee99eSArd Biesheuvel int err; 231*1abee99eSArd Biesheuvel 232*1abee99eSArd Biesheuvel err = xts_verify_key(tfm, in_key, key_len); 233*1abee99eSArd Biesheuvel if (err) 234*1abee99eSArd Biesheuvel return err; 235*1abee99eSArd Biesheuvel 236*1abee99eSArd Biesheuvel key_len /= 2; 237*1abee99eSArd Biesheuvel err = crypto_aes_expand_key(&rk, in_key + key_len, key_len); 238*1abee99eSArd Biesheuvel if (err) 239*1abee99eSArd Biesheuvel return err; 240*1abee99eSArd Biesheuvel 241*1abee99eSArd Biesheuvel memcpy(ctx->twkey, rk.key_enc, sizeof(ctx->twkey)); 242*1abee99eSArd Biesheuvel 243*1abee99eSArd Biesheuvel return aesbs_setkey(tfm, in_key, key_len); 244*1abee99eSArd Biesheuvel } 245*1abee99eSArd Biesheuvel 246*1abee99eSArd Biesheuvel static int __xts_crypt(struct skcipher_request *req, 247*1abee99eSArd Biesheuvel void (*fn)(u8 out[], u8 const in[], u8 const rk[], 248*1abee99eSArd Biesheuvel int rounds, int blocks, u8 iv[])) 249*1abee99eSArd Biesheuvel { 250*1abee99eSArd Biesheuvel struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 251*1abee99eSArd Biesheuvel struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); 252*1abee99eSArd Biesheuvel struct skcipher_walk walk; 253*1abee99eSArd Biesheuvel int err; 254*1abee99eSArd Biesheuvel 255*1abee99eSArd Biesheuvel err = skcipher_walk_virt(&walk, req, true); 256*1abee99eSArd Biesheuvel 257*1abee99eSArd Biesheuvel __aes_arm64_encrypt(ctx->twkey, walk.iv, walk.iv, ctx->key.rounds); 258*1abee99eSArd Biesheuvel 259*1abee99eSArd Biesheuvel kernel_neon_begin(); 260*1abee99eSArd Biesheuvel while (walk.nbytes >= AES_BLOCK_SIZE) { 261*1abee99eSArd Biesheuvel unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE; 262*1abee99eSArd Biesheuvel 263*1abee99eSArd Biesheuvel if (walk.nbytes < walk.total) 264*1abee99eSArd Biesheuvel blocks = round_down(blocks, 265*1abee99eSArd Biesheuvel walk.stride / AES_BLOCK_SIZE); 266*1abee99eSArd Biesheuvel 267*1abee99eSArd Biesheuvel fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->key.rk, 268*1abee99eSArd Biesheuvel ctx->key.rounds, blocks, walk.iv); 269*1abee99eSArd Biesheuvel err = skcipher_walk_done(&walk, 270*1abee99eSArd Biesheuvel walk.nbytes - blocks * AES_BLOCK_SIZE); 271*1abee99eSArd Biesheuvel } 272*1abee99eSArd Biesheuvel kernel_neon_end(); 273*1abee99eSArd Biesheuvel 274*1abee99eSArd Biesheuvel return err; 275*1abee99eSArd Biesheuvel } 276*1abee99eSArd Biesheuvel 277*1abee99eSArd Biesheuvel static int xts_encrypt(struct skcipher_request *req) 278*1abee99eSArd Biesheuvel { 279*1abee99eSArd Biesheuvel return __xts_crypt(req, aesbs_xts_encrypt); 280*1abee99eSArd Biesheuvel } 281*1abee99eSArd Biesheuvel 282*1abee99eSArd Biesheuvel static int xts_decrypt(struct skcipher_request *req) 283*1abee99eSArd Biesheuvel { 284*1abee99eSArd Biesheuvel return __xts_crypt(req, aesbs_xts_decrypt); 285*1abee99eSArd Biesheuvel } 286*1abee99eSArd Biesheuvel 287*1abee99eSArd Biesheuvel static struct skcipher_alg aes_algs[] = { { 288*1abee99eSArd Biesheuvel .base.cra_name = "__ecb(aes)", 289*1abee99eSArd Biesheuvel .base.cra_driver_name = "__ecb-aes-neonbs", 290*1abee99eSArd Biesheuvel .base.cra_priority = 250, 291*1abee99eSArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 292*1abee99eSArd Biesheuvel .base.cra_ctxsize = sizeof(struct aesbs_ctx), 293*1abee99eSArd Biesheuvel .base.cra_module = THIS_MODULE, 294*1abee99eSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_INTERNAL, 295*1abee99eSArd Biesheuvel 296*1abee99eSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 297*1abee99eSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 298*1abee99eSArd Biesheuvel .walksize = 8 * AES_BLOCK_SIZE, 299*1abee99eSArd Biesheuvel .setkey = aesbs_setkey, 300*1abee99eSArd Biesheuvel .encrypt = ecb_encrypt, 301*1abee99eSArd Biesheuvel .decrypt = ecb_decrypt, 302*1abee99eSArd Biesheuvel }, { 303*1abee99eSArd Biesheuvel .base.cra_name = "__cbc(aes)", 304*1abee99eSArd Biesheuvel .base.cra_driver_name = "__cbc-aes-neonbs", 305*1abee99eSArd Biesheuvel .base.cra_priority = 250, 306*1abee99eSArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 307*1abee99eSArd Biesheuvel .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctx), 308*1abee99eSArd Biesheuvel .base.cra_module = THIS_MODULE, 309*1abee99eSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_INTERNAL, 310*1abee99eSArd Biesheuvel 311*1abee99eSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 312*1abee99eSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 313*1abee99eSArd Biesheuvel .walksize = 8 * AES_BLOCK_SIZE, 314*1abee99eSArd Biesheuvel .ivsize = AES_BLOCK_SIZE, 315*1abee99eSArd Biesheuvel .setkey = aesbs_cbc_setkey, 316*1abee99eSArd Biesheuvel .encrypt = cbc_encrypt, 317*1abee99eSArd Biesheuvel .decrypt = cbc_decrypt, 318*1abee99eSArd Biesheuvel }, { 319*1abee99eSArd Biesheuvel .base.cra_name = "__ctr(aes)", 320*1abee99eSArd Biesheuvel .base.cra_driver_name = "__ctr-aes-neonbs", 321*1abee99eSArd Biesheuvel .base.cra_priority = 250, 322*1abee99eSArd Biesheuvel .base.cra_blocksize = 1, 323*1abee99eSArd Biesheuvel .base.cra_ctxsize = sizeof(struct aesbs_ctx), 324*1abee99eSArd Biesheuvel .base.cra_module = THIS_MODULE, 325*1abee99eSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_INTERNAL, 326*1abee99eSArd Biesheuvel 327*1abee99eSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 328*1abee99eSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 329*1abee99eSArd Biesheuvel .chunksize = AES_BLOCK_SIZE, 330*1abee99eSArd Biesheuvel .walksize = 8 * AES_BLOCK_SIZE, 331*1abee99eSArd Biesheuvel .ivsize = AES_BLOCK_SIZE, 332*1abee99eSArd Biesheuvel .setkey = aesbs_setkey, 333*1abee99eSArd Biesheuvel .encrypt = ctr_encrypt, 334*1abee99eSArd Biesheuvel .decrypt = ctr_encrypt, 335*1abee99eSArd Biesheuvel }, { 336*1abee99eSArd Biesheuvel .base.cra_name = "ctr(aes)", 337*1abee99eSArd Biesheuvel .base.cra_driver_name = "ctr-aes-neonbs", 338*1abee99eSArd Biesheuvel .base.cra_priority = 250 - 1, 339*1abee99eSArd Biesheuvel .base.cra_blocksize = 1, 340*1abee99eSArd Biesheuvel .base.cra_ctxsize = sizeof(struct aesbs_ctx), 341*1abee99eSArd Biesheuvel .base.cra_module = THIS_MODULE, 342*1abee99eSArd Biesheuvel 343*1abee99eSArd Biesheuvel .min_keysize = AES_MIN_KEY_SIZE, 344*1abee99eSArd Biesheuvel .max_keysize = AES_MAX_KEY_SIZE, 345*1abee99eSArd Biesheuvel .chunksize = AES_BLOCK_SIZE, 346*1abee99eSArd Biesheuvel .walksize = 8 * AES_BLOCK_SIZE, 347*1abee99eSArd Biesheuvel .ivsize = AES_BLOCK_SIZE, 348*1abee99eSArd Biesheuvel .setkey = aesbs_setkey, 349*1abee99eSArd Biesheuvel .encrypt = ctr_encrypt, 350*1abee99eSArd Biesheuvel .decrypt = ctr_encrypt, 351*1abee99eSArd Biesheuvel }, { 352*1abee99eSArd Biesheuvel .base.cra_name = "__xts(aes)", 353*1abee99eSArd Biesheuvel .base.cra_driver_name = "__xts-aes-neonbs", 354*1abee99eSArd Biesheuvel .base.cra_priority = 250, 355*1abee99eSArd Biesheuvel .base.cra_blocksize = AES_BLOCK_SIZE, 356*1abee99eSArd Biesheuvel .base.cra_ctxsize = sizeof(struct aesbs_xts_ctx), 357*1abee99eSArd Biesheuvel .base.cra_module = THIS_MODULE, 358*1abee99eSArd Biesheuvel .base.cra_flags = CRYPTO_ALG_INTERNAL, 359*1abee99eSArd Biesheuvel 360*1abee99eSArd Biesheuvel .min_keysize = 2 * AES_MIN_KEY_SIZE, 361*1abee99eSArd Biesheuvel .max_keysize = 2 * AES_MAX_KEY_SIZE, 362*1abee99eSArd Biesheuvel .walksize = 8 * AES_BLOCK_SIZE, 363*1abee99eSArd Biesheuvel .ivsize = AES_BLOCK_SIZE, 364*1abee99eSArd Biesheuvel .setkey = aesbs_xts_setkey, 365*1abee99eSArd Biesheuvel .encrypt = xts_encrypt, 366*1abee99eSArd Biesheuvel .decrypt = xts_decrypt, 367*1abee99eSArd Biesheuvel } }; 368*1abee99eSArd Biesheuvel 369*1abee99eSArd Biesheuvel static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)]; 370*1abee99eSArd Biesheuvel 371*1abee99eSArd Biesheuvel static void aes_exit(void) 372*1abee99eSArd Biesheuvel { 373*1abee99eSArd Biesheuvel int i; 374*1abee99eSArd Biesheuvel 375*1abee99eSArd Biesheuvel for (i = 0; i < ARRAY_SIZE(aes_simd_algs); i++) 376*1abee99eSArd Biesheuvel if (aes_simd_algs[i]) 377*1abee99eSArd Biesheuvel simd_skcipher_free(aes_simd_algs[i]); 378*1abee99eSArd Biesheuvel 379*1abee99eSArd Biesheuvel crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); 380*1abee99eSArd Biesheuvel } 381*1abee99eSArd Biesheuvel 382*1abee99eSArd Biesheuvel static int __init aes_init(void) 383*1abee99eSArd Biesheuvel { 384*1abee99eSArd Biesheuvel struct simd_skcipher_alg *simd; 385*1abee99eSArd Biesheuvel const char *basename; 386*1abee99eSArd Biesheuvel const char *algname; 387*1abee99eSArd Biesheuvel const char *drvname; 388*1abee99eSArd Biesheuvel int err; 389*1abee99eSArd Biesheuvel int i; 390*1abee99eSArd Biesheuvel 391*1abee99eSArd Biesheuvel if (!(elf_hwcap & HWCAP_ASIMD)) 392*1abee99eSArd Biesheuvel return -ENODEV; 393*1abee99eSArd Biesheuvel 394*1abee99eSArd Biesheuvel err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs)); 395*1abee99eSArd Biesheuvel if (err) 396*1abee99eSArd Biesheuvel return err; 397*1abee99eSArd Biesheuvel 398*1abee99eSArd Biesheuvel for (i = 0; i < ARRAY_SIZE(aes_algs); i++) { 399*1abee99eSArd Biesheuvel if (!(aes_algs[i].base.cra_flags & CRYPTO_ALG_INTERNAL)) 400*1abee99eSArd Biesheuvel continue; 401*1abee99eSArd Biesheuvel 402*1abee99eSArd Biesheuvel algname = aes_algs[i].base.cra_name + 2; 403*1abee99eSArd Biesheuvel drvname = aes_algs[i].base.cra_driver_name + 2; 404*1abee99eSArd Biesheuvel basename = aes_algs[i].base.cra_driver_name; 405*1abee99eSArd Biesheuvel simd = simd_skcipher_create_compat(algname, drvname, basename); 406*1abee99eSArd Biesheuvel err = PTR_ERR(simd); 407*1abee99eSArd Biesheuvel if (IS_ERR(simd)) 408*1abee99eSArd Biesheuvel goto unregister_simds; 409*1abee99eSArd Biesheuvel 410*1abee99eSArd Biesheuvel aes_simd_algs[i] = simd; 411*1abee99eSArd Biesheuvel } 412*1abee99eSArd Biesheuvel return 0; 413*1abee99eSArd Biesheuvel 414*1abee99eSArd Biesheuvel unregister_simds: 415*1abee99eSArd Biesheuvel aes_exit(); 416*1abee99eSArd Biesheuvel return err; 417*1abee99eSArd Biesheuvel } 418*1abee99eSArd Biesheuvel 419*1abee99eSArd Biesheuvel module_init(aes_init); 420*1abee99eSArd Biesheuvel module_exit(aes_exit); 421