crypto: x86/aes-ni-xts - rewrite and drop indirections via glue helper

The AES-NI driver implements XTS via the glue helper, which consumes
a struct with sets of function pointers which are invoked on chunks
of input data of the appropriate size, as annotated in the struct.

Let's get rid of this indirection, so that we can perform direct calls
to the assembler helpers. Instead, let's adopt the arm64 strategy, i.e.,
provide a helper which can consume inputs of any size, provided that the
penultimate, full block is passed via the last call if ciphertext stealing
needs to be applied.

This also allows us to enable the XTS mode for i386.

Tested-by: Eric Biggers <ebiggers@google.com> # x86_64
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Ard Biesheuvel 2020-12-31 17:41:55 +01:00 коммит произвёл Herbert Xu
Родитель 86ad60a65f
Коммит 2481104fe9
3 изменённых файлов: 356 добавлений и 145 удалений

Просмотреть файл

@ -43,10 +43,6 @@
#ifdef __x86_64__ #ifdef __x86_64__
# constants in mergeable sections, linker can reorder and merge # constants in mergeable sections, linker can reorder and merge
.section .rodata.cst16.gf128mul_x_ble_mask, "aM", @progbits, 16
.align 16
.Lgf128mul_x_ble_mask:
.octa 0x00000000000000010000000000000087
.section .rodata.cst16.POLY, "aM", @progbits, 16 .section .rodata.cst16.POLY, "aM", @progbits, 16
.align 16 .align 16
POLY: .octa 0xC2000000000000000000000000000001 POLY: .octa 0xC2000000000000000000000000000001
@ -146,7 +142,7 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
#define CTR %xmm11 #define CTR %xmm11
#define INC %xmm12 #define INC %xmm12
#define GF128MUL_MASK %xmm10 #define GF128MUL_MASK %xmm7
#ifdef __x86_64__ #ifdef __x86_64__
#define AREG %rax #define AREG %rax
@ -2823,6 +2819,14 @@ SYM_FUNC_START(aesni_ctr_enc)
ret ret
SYM_FUNC_END(aesni_ctr_enc) SYM_FUNC_END(aesni_ctr_enc)
#endif
.section .rodata.cst16.gf128mul_x_ble_mask, "aM", @progbits, 16
.align 16
.Lgf128mul_x_ble_mask:
.octa 0x00000000000000010000000000000087
.previous
/* /*
* _aesni_gf128mul_x_ble: internal ABI * _aesni_gf128mul_x_ble: internal ABI
* Multiply in GF(2^128) for XTS IVs * Multiply in GF(2^128) for XTS IVs
@ -2835,11 +2839,11 @@ SYM_FUNC_END(aesni_ctr_enc)
* CTR: == temporary value * CTR: == temporary value
*/ */
#define _aesni_gf128mul_x_ble() \ #define _aesni_gf128mul_x_ble() \
pshufd $0x13, IV, CTR; \ pshufd $0x13, IV, KEY; \
paddq IV, IV; \ paddq IV, IV; \
psrad $31, CTR; \ psrad $31, KEY; \
pand GF128MUL_MASK, CTR; \ pand GF128MUL_MASK, KEY; \
pxor CTR, IV; pxor KEY, IV;
/* /*
* void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, * void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst,
@ -2847,65 +2851,153 @@ SYM_FUNC_END(aesni_ctr_enc)
*/ */
SYM_FUNC_START(aesni_xts_encrypt) SYM_FUNC_START(aesni_xts_encrypt)
FRAME_BEGIN FRAME_BEGIN
#ifndef __x86_64__
pushl IVP
pushl LEN
pushl KEYP
pushl KLEN
movl (FRAME_OFFSET+20)(%esp), KEYP # ctx
movl (FRAME_OFFSET+24)(%esp), OUTP # dst
movl (FRAME_OFFSET+28)(%esp), INP # src
movl (FRAME_OFFSET+32)(%esp), LEN # len
movl (FRAME_OFFSET+36)(%esp), IVP # iv
movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK
#else
movdqa .Lgf128mul_x_ble_mask(%rip), GF128MUL_MASK
#endif
movups (IVP), IV movups (IVP), IV
mov 480(KEYP), KLEN mov 480(KEYP), KLEN
.Lxts_enc_loop4: .Lxts_enc_loop4:
sub $64, LEN
jl .Lxts_enc_1x
movdqa IV, STATE1 movdqa IV, STATE1
movdqu 0x00(INP), INC movdqu 0x00(INP), IN
pxor INC, STATE1 pxor IN, STATE1
movdqu IV, 0x00(OUTP) movdqu IV, 0x00(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE2 movdqa IV, STATE2
movdqu 0x10(INP), INC movdqu 0x10(INP), IN
pxor INC, STATE2 pxor IN, STATE2
movdqu IV, 0x10(OUTP) movdqu IV, 0x10(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE3 movdqa IV, STATE3
movdqu 0x20(INP), INC movdqu 0x20(INP), IN
pxor INC, STATE3 pxor IN, STATE3
movdqu IV, 0x20(OUTP) movdqu IV, 0x20(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE4 movdqa IV, STATE4
movdqu 0x30(INP), INC movdqu 0x30(INP), IN
pxor INC, STATE4 pxor IN, STATE4
movdqu IV, 0x30(OUTP) movdqu IV, 0x30(OUTP)
call _aesni_enc4 call _aesni_enc4
movdqu 0x00(OUTP), INC movdqu 0x00(OUTP), IN
pxor INC, STATE1 pxor IN, STATE1
movdqu STATE1, 0x00(OUTP) movdqu STATE1, 0x00(OUTP)
movdqu 0x10(OUTP), INC movdqu 0x10(OUTP), IN
pxor INC, STATE2 pxor IN, STATE2
movdqu STATE2, 0x10(OUTP) movdqu STATE2, 0x10(OUTP)
movdqu 0x20(OUTP), INC movdqu 0x20(OUTP), IN
pxor INC, STATE3 pxor IN, STATE3
movdqu STATE3, 0x20(OUTP) movdqu STATE3, 0x20(OUTP)
movdqu 0x30(OUTP), INC movdqu 0x30(OUTP), IN
pxor INC, STATE4 pxor IN, STATE4
movdqu STATE4, 0x30(OUTP) movdqu STATE4, 0x30(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
add $64, INP add $64, INP
add $64, OUTP add $64, OUTP
sub $64, LEN test LEN, LEN
ja .Lxts_enc_loop4 jnz .Lxts_enc_loop4
.Lxts_enc_ret_iv:
movups IV, (IVP) movups IV, (IVP)
.Lxts_enc_ret:
#ifndef __x86_64__
popl KLEN
popl KEYP
popl LEN
popl IVP
#endif
FRAME_END FRAME_END
ret ret
.Lxts_enc_1x:
add $64, LEN
jz .Lxts_enc_ret_iv
sub $16, LEN
jl .Lxts_enc_cts4
.Lxts_enc_loop1:
movdqu (INP), STATE
pxor IV, STATE
call _aesni_enc1
pxor IV, STATE
_aesni_gf128mul_x_ble()
test LEN, LEN
jz .Lxts_enc_out
add $16, INP
sub $16, LEN
jl .Lxts_enc_cts1
movdqu STATE, (OUTP)
add $16, OUTP
jmp .Lxts_enc_loop1
.Lxts_enc_out:
movdqu STATE, (OUTP)
jmp .Lxts_enc_ret_iv
.Lxts_enc_cts4:
movdqa STATE4, STATE
sub $16, OUTP
.Lxts_enc_cts1:
#ifndef __x86_64__
lea .Lcts_permute_table, T1
#else
lea .Lcts_permute_table(%rip), T1
#endif
add LEN, INP /* rewind input pointer */
add $16, LEN /* # bytes in final block */
movups (INP), IN1
mov T1, IVP
add $32, IVP
add LEN, T1
sub LEN, IVP
add OUTP, LEN
movups (T1), %xmm4
movaps STATE, IN2
pshufb %xmm4, STATE
movups STATE, (LEN)
movups (IVP), %xmm0
pshufb %xmm0, IN1
pblendvb IN2, IN1
movaps IN1, STATE
pxor IV, STATE
call _aesni_enc1
pxor IV, STATE
movups STATE, (OUTP)
jmp .Lxts_enc_ret
SYM_FUNC_END(aesni_xts_encrypt) SYM_FUNC_END(aesni_xts_encrypt)
/* /*
@ -2914,66 +3006,158 @@ SYM_FUNC_END(aesni_xts_encrypt)
*/ */
SYM_FUNC_START(aesni_xts_decrypt) SYM_FUNC_START(aesni_xts_decrypt)
FRAME_BEGIN FRAME_BEGIN
#ifndef __x86_64__
pushl IVP
pushl LEN
pushl KEYP
pushl KLEN
movl (FRAME_OFFSET+20)(%esp), KEYP # ctx
movl (FRAME_OFFSET+24)(%esp), OUTP # dst
movl (FRAME_OFFSET+28)(%esp), INP # src
movl (FRAME_OFFSET+32)(%esp), LEN # len
movl (FRAME_OFFSET+36)(%esp), IVP # iv
movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK
#else
movdqa .Lgf128mul_x_ble_mask(%rip), GF128MUL_MASK
#endif
movups (IVP), IV movups (IVP), IV
mov 480(KEYP), KLEN mov 480(KEYP), KLEN
add $240, KEYP add $240, KEYP
test $15, LEN
jz .Lxts_dec_loop4
sub $16, LEN
.Lxts_dec_loop4: .Lxts_dec_loop4:
sub $64, LEN
jl .Lxts_dec_1x
movdqa IV, STATE1 movdqa IV, STATE1
movdqu 0x00(INP), INC movdqu 0x00(INP), IN
pxor INC, STATE1 pxor IN, STATE1
movdqu IV, 0x00(OUTP) movdqu IV, 0x00(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE2 movdqa IV, STATE2
movdqu 0x10(INP), INC movdqu 0x10(INP), IN
pxor INC, STATE2 pxor IN, STATE2
movdqu IV, 0x10(OUTP) movdqu IV, 0x10(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE3 movdqa IV, STATE3
movdqu 0x20(INP), INC movdqu 0x20(INP), IN
pxor INC, STATE3 pxor IN, STATE3
movdqu IV, 0x20(OUTP) movdqu IV, 0x20(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
movdqa IV, STATE4 movdqa IV, STATE4
movdqu 0x30(INP), INC movdqu 0x30(INP), IN
pxor INC, STATE4 pxor IN, STATE4
movdqu IV, 0x30(OUTP) movdqu IV, 0x30(OUTP)
call _aesni_dec4 call _aesni_dec4
movdqu 0x00(OUTP), INC movdqu 0x00(OUTP), IN
pxor INC, STATE1 pxor IN, STATE1
movdqu STATE1, 0x00(OUTP) movdqu STATE1, 0x00(OUTP)
movdqu 0x10(OUTP), INC movdqu 0x10(OUTP), IN
pxor INC, STATE2 pxor IN, STATE2
movdqu STATE2, 0x10(OUTP) movdqu STATE2, 0x10(OUTP)
movdqu 0x20(OUTP), INC movdqu 0x20(OUTP), IN
pxor INC, STATE3 pxor IN, STATE3
movdqu STATE3, 0x20(OUTP) movdqu STATE3, 0x20(OUTP)
movdqu 0x30(OUTP), INC movdqu 0x30(OUTP), IN
pxor INC, STATE4 pxor IN, STATE4
movdqu STATE4, 0x30(OUTP) movdqu STATE4, 0x30(OUTP)
_aesni_gf128mul_x_ble() _aesni_gf128mul_x_ble()
add $64, INP add $64, INP
add $64, OUTP add $64, OUTP
sub $64, LEN test LEN, LEN
ja .Lxts_dec_loop4 jnz .Lxts_dec_loop4
.Lxts_dec_ret_iv:
movups IV, (IVP) movups IV, (IVP)
.Lxts_dec_ret:
#ifndef __x86_64__
popl KLEN
popl KEYP
popl LEN
popl IVP
#endif
FRAME_END FRAME_END
ret ret
SYM_FUNC_END(aesni_xts_decrypt)
.Lxts_dec_1x:
add $64, LEN
jz .Lxts_dec_ret_iv
.Lxts_dec_loop1:
movdqu (INP), STATE
add $16, INP
sub $16, LEN
jl .Lxts_dec_cts1
pxor IV, STATE
call _aesni_dec1
pxor IV, STATE
_aesni_gf128mul_x_ble()
test LEN, LEN
jz .Lxts_dec_out
movdqu STATE, (OUTP)
add $16, OUTP
jmp .Lxts_dec_loop1
.Lxts_dec_out:
movdqu STATE, (OUTP)
jmp .Lxts_dec_ret_iv
.Lxts_dec_cts1:
movdqa IV, STATE4
_aesni_gf128mul_x_ble()
pxor IV, STATE
call _aesni_dec1
pxor IV, STATE
#ifndef __x86_64__
lea .Lcts_permute_table, T1
#else
lea .Lcts_permute_table(%rip), T1
#endif #endif
add LEN, INP /* rewind input pointer */
add $16, LEN /* # bytes in final block */
movups (INP), IN1
mov T1, IVP
add $32, IVP
add LEN, T1
sub LEN, IVP
add OUTP, LEN
movups (T1), %xmm4
movaps STATE, IN2
pshufb %xmm4, STATE
movups STATE, (LEN)
movups (IVP), %xmm0
pshufb %xmm0, IN1
pblendvb IN2, IN1
movaps IN1, STATE
pxor STATE4, STATE
call _aesni_dec1
pxor STATE4, STATE
movups STATE, (OUTP)
jmp .Lxts_dec_ret
SYM_FUNC_END(aesni_xts_decrypt)

Просмотреть файл

@ -33,9 +33,6 @@
#include <crypto/internal/skcipher.h> #include <crypto/internal/skcipher.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#ifdef CONFIG_X86_64
#include <asm/crypto/glue_helper.h>
#endif
#define AESNI_ALIGN 16 #define AESNI_ALIGN 16
@ -632,98 +629,6 @@ static int ctr_crypt(struct skcipher_request *req)
return err; return err;
} }
static int xts_aesni_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen)
{
struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
int err;
err = xts_verify_key(tfm, key, keylen);
if (err)
return err;
keylen /= 2;
/* first half of xts-key is for crypt */
err = aes_set_key_common(crypto_skcipher_tfm(tfm), ctx->raw_crypt_ctx,
key, keylen);
if (err)
return err;
/* second half of xts-key is for tweak */
return aes_set_key_common(crypto_skcipher_tfm(tfm), ctx->raw_tweak_ctx,
key + keylen, keylen);
}
static void aesni_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
{
glue_xts_crypt_128bit_one(ctx, dst, src, iv, aesni_enc);
}
static void aesni_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
{
glue_xts_crypt_128bit_one(ctx, dst, src, iv, aesni_dec);
}
static void aesni_xts_enc32(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
{
aesni_xts_encrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv);
}
static void aesni_xts_dec32(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
{
aesni_xts_decrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv);
}
static const struct common_glue_ctx aesni_enc_xts = {
.num_funcs = 2,
.fpu_blocks_limit = 1,
.funcs = { {
.num_blocks = 32,
.fn_u = { .xts = aesni_xts_enc32 }
}, {
.num_blocks = 1,
.fn_u = { .xts = aesni_xts_enc }
} }
};
static const struct common_glue_ctx aesni_dec_xts = {
.num_funcs = 2,
.fpu_blocks_limit = 1,
.funcs = { {
.num_blocks = 32,
.fn_u = { .xts = aesni_xts_dec32 }
}, {
.num_blocks = 1,
.fn_u = { .xts = aesni_xts_dec }
} }
};
static int xts_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
return glue_xts_req_128bit(&aesni_enc_xts, req, aesni_enc,
aes_ctx(ctx->raw_tweak_ctx),
aes_ctx(ctx->raw_crypt_ctx),
false);
}
static int xts_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
return glue_xts_req_128bit(&aesni_dec_xts, req, aesni_enc,
aes_ctx(ctx->raw_tweak_ctx),
aes_ctx(ctx->raw_crypt_ctx),
true);
}
static int static int
rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len) rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
{ {
@ -996,6 +901,128 @@ static int helper_rfc4106_decrypt(struct aead_request *req)
} }
#endif #endif
static int xts_aesni_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen)
{
struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
int err;
err = xts_verify_key(tfm, key, keylen);
if (err)
return err;
keylen /= 2;
/* first half of xts-key is for crypt */
err = aes_set_key_common(crypto_skcipher_tfm(tfm), ctx->raw_crypt_ctx,
key, keylen);
if (err)
return err;
/* second half of xts-key is for tweak */
return aes_set_key_common(crypto_skcipher_tfm(tfm), ctx->raw_tweak_ctx,
key + keylen, keylen);
}
static int xts_crypt(struct skcipher_request *req, bool encrypt)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
int tail = req->cryptlen % AES_BLOCK_SIZE;
struct skcipher_request subreq;
struct skcipher_walk walk;
int err;
if (req->cryptlen < AES_BLOCK_SIZE)
return -EINVAL;
err = skcipher_walk_virt(&walk, req, false);
if (unlikely(tail > 0 && walk.nbytes < walk.total)) {
int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
skcipher_walk_abort(&walk);
skcipher_request_set_tfm(&subreq, tfm);
skcipher_request_set_callback(&subreq,
skcipher_request_flags(req),
NULL, NULL);
skcipher_request_set_crypt(&subreq, req->src, req->dst,
blocks * AES_BLOCK_SIZE, req->iv);
req = &subreq;
err = skcipher_walk_virt(&walk, req, false);
} else {
tail = 0;
}
kernel_fpu_begin();
/* calculate first value of T */
aesni_enc(aes_ctx(ctx->raw_tweak_ctx), walk.iv, walk.iv);
while (walk.nbytes > 0) {
int nbytes = walk.nbytes;
if (nbytes < walk.total)
nbytes &= ~(AES_BLOCK_SIZE - 1);
if (encrypt)
aesni_xts_encrypt(aes_ctx(ctx->raw_crypt_ctx),
walk.dst.virt.addr, walk.src.virt.addr,
nbytes, walk.iv);
else
aesni_xts_decrypt(aes_ctx(ctx->raw_crypt_ctx),
walk.dst.virt.addr, walk.src.virt.addr,
nbytes, walk.iv);
kernel_fpu_end();
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
if (walk.nbytes > 0)
kernel_fpu_begin();
}
if (unlikely(tail > 0 && !err)) {
struct scatterlist sg_src[2], sg_dst[2];
struct scatterlist *src, *dst;
dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
if (req->dst != req->src)
dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
req->iv);
err = skcipher_walk_virt(&walk, &subreq, false);
if (err)
return err;
kernel_fpu_begin();
if (encrypt)
aesni_xts_encrypt(aes_ctx(ctx->raw_crypt_ctx),
walk.dst.virt.addr, walk.src.virt.addr,
walk.nbytes, walk.iv);
else
aesni_xts_decrypt(aes_ctx(ctx->raw_crypt_ctx),
walk.dst.virt.addr, walk.src.virt.addr,
walk.nbytes, walk.iv);
kernel_fpu_end();
err = skcipher_walk_done(&walk, 0);
}
return err;
}
static int xts_encrypt(struct skcipher_request *req)
{
return xts_crypt(req, true);
}
static int xts_decrypt(struct skcipher_request *req)
{
return xts_crypt(req, false);
}
static struct crypto_alg aesni_cipher_alg = { static struct crypto_alg aesni_cipher_alg = {
.cra_name = "aes", .cra_name = "aes",
.cra_driver_name = "aes-aesni", .cra_driver_name = "aes-aesni",
@ -1082,6 +1109,7 @@ static struct skcipher_alg aesni_skciphers[] = {
.setkey = aesni_skcipher_setkey, .setkey = aesni_skcipher_setkey,
.encrypt = ctr_crypt, .encrypt = ctr_crypt,
.decrypt = ctr_crypt, .decrypt = ctr_crypt,
#endif
}, { }, {
.base = { .base = {
.cra_name = "__xts(aes)", .cra_name = "__xts(aes)",
@ -1095,10 +1123,10 @@ static struct skcipher_alg aesni_skciphers[] = {
.min_keysize = 2 * AES_MIN_KEY_SIZE, .min_keysize = 2 * AES_MIN_KEY_SIZE,
.max_keysize = 2 * AES_MAX_KEY_SIZE, .max_keysize = 2 * AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE, .ivsize = AES_BLOCK_SIZE,
.walksize = 2 * AES_BLOCK_SIZE,
.setkey = xts_aesni_setkey, .setkey = xts_aesni_setkey,
.encrypt = xts_encrypt, .encrypt = xts_encrypt,
.decrypt = xts_decrypt, .decrypt = xts_decrypt,
#endif
} }
}; };

Просмотреть файл

@ -1133,7 +1133,6 @@ config CRYPTO_AES_NI_INTEL
select CRYPTO_LIB_AES select CRYPTO_LIB_AES
select CRYPTO_ALGAPI select CRYPTO_ALGAPI
select CRYPTO_SKCIPHER select CRYPTO_SKCIPHER
select CRYPTO_GLUE_HELPER_X86 if 64BIT
select CRYPTO_SIMD select CRYPTO_SIMD
help help
Use Intel AES-NI instructions for AES algorithm. Use Intel AES-NI instructions for AES algorithm.