提交 cf3d41ad 编写于 作者: A Ard Biesheuvel 提交者: Herbert Xu

crypto: aegis128 - add support for SIMD acceleration

Add some plumbing to allow the AEGIS128 code to be built with SIMD
routines for acceleration.
Reviewed-by: NOndrej Mosnacek <omosnace@redhat.com>
Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
上级 8083b1bf
...@@ -90,6 +90,7 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o ...@@ -90,6 +90,7 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o
obj-$(CONFIG_CRYPTO_CCM) += ccm.o obj-$(CONFIG_CRYPTO_CCM) += ccm.o
obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o
aegis128-y := aegis128-core.o
obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
obj-$(CONFIG_CRYPTO_DES) += des_generic.o obj-$(CONFIG_CRYPTO_DES) += des_generic.o
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <crypto/algapi.h> #include <crypto/algapi.h>
#include <crypto/internal/aead.h> #include <crypto/internal/aead.h>
#include <crypto/internal/simd.h>
#include <crypto/internal/skcipher.h> #include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h> #include <crypto/scatterwalk.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -16,6 +17,8 @@ ...@@ -16,6 +17,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <asm/simd.h>
#include "aegis.h" #include "aegis.h"
#define AEGIS128_NONCE_SIZE 16 #define AEGIS128_NONCE_SIZE 16
...@@ -40,6 +43,24 @@ struct aegis128_ops { ...@@ -40,6 +43,24 @@ struct aegis128_ops {
const u8 *src, unsigned int size); const u8 *src, unsigned int size);
}; };
static bool have_simd;
static bool aegis128_do_simd(void)
{
#ifdef CONFIG_CRYPTO_AEGIS128_SIMD
if (have_simd)
return crypto_simd_usable();
#endif
return false;
}
bool crypto_aegis128_have_simd(void);
void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg);
void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size);
void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size);
static void crypto_aegis128_update(struct aegis_state *state) static void crypto_aegis128_update(struct aegis_state *state)
{ {
union aegis_block tmp; union aegis_block tmp;
...@@ -55,12 +76,22 @@ static void crypto_aegis128_update(struct aegis_state *state) ...@@ -55,12 +76,22 @@ static void crypto_aegis128_update(struct aegis_state *state)
static void crypto_aegis128_update_a(struct aegis_state *state, static void crypto_aegis128_update_a(struct aegis_state *state,
const union aegis_block *msg) const union aegis_block *msg)
{ {
if (aegis128_do_simd()) {
crypto_aegis128_update_simd(state, msg);
return;
}
crypto_aegis128_update(state); crypto_aegis128_update(state);
crypto_aegis_block_xor(&state->blocks[0], msg); crypto_aegis_block_xor(&state->blocks[0], msg);
} }
static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg) static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg)
{ {
if (aegis128_do_simd()) {
crypto_aegis128_update_simd(state, msg);
return;
}
crypto_aegis128_update(state); crypto_aegis128_update(state);
crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE); crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE);
} }
...@@ -365,7 +396,7 @@ static void crypto_aegis128_crypt(struct aead_request *req, ...@@ -365,7 +396,7 @@ static void crypto_aegis128_crypt(struct aead_request *req,
static int crypto_aegis128_encrypt(struct aead_request *req) static int crypto_aegis128_encrypt(struct aead_request *req)
{ {
static const struct aegis128_ops ops = { const struct aegis128_ops *ops = &(struct aegis128_ops){
.skcipher_walk_init = skcipher_walk_aead_encrypt, .skcipher_walk_init = skcipher_walk_aead_encrypt,
.crypt_chunk = crypto_aegis128_encrypt_chunk, .crypt_chunk = crypto_aegis128_encrypt_chunk,
}; };
...@@ -375,7 +406,12 @@ static int crypto_aegis128_encrypt(struct aead_request *req) ...@@ -375,7 +406,12 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
unsigned int authsize = crypto_aead_authsize(tfm); unsigned int authsize = crypto_aead_authsize(tfm);
unsigned int cryptlen = req->cryptlen; unsigned int cryptlen = req->cryptlen;
crypto_aegis128_crypt(req, &tag, cryptlen, &ops); if (aegis128_do_simd())
ops = &(struct aegis128_ops){
.skcipher_walk_init = skcipher_walk_aead_encrypt,
.crypt_chunk = crypto_aegis128_encrypt_chunk_simd };
crypto_aegis128_crypt(req, &tag, cryptlen, ops);
scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen, scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
authsize, 1); authsize, 1);
...@@ -384,7 +420,7 @@ static int crypto_aegis128_encrypt(struct aead_request *req) ...@@ -384,7 +420,7 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
static int crypto_aegis128_decrypt(struct aead_request *req) static int crypto_aegis128_decrypt(struct aead_request *req)
{ {
static const struct aegis128_ops ops = { const struct aegis128_ops *ops = &(struct aegis128_ops){
.skcipher_walk_init = skcipher_walk_aead_decrypt, .skcipher_walk_init = skcipher_walk_aead_decrypt,
.crypt_chunk = crypto_aegis128_decrypt_chunk, .crypt_chunk = crypto_aegis128_decrypt_chunk,
}; };
...@@ -398,7 +434,12 @@ static int crypto_aegis128_decrypt(struct aead_request *req) ...@@ -398,7 +434,12 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen, scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
authsize, 0); authsize, 0);
crypto_aegis128_crypt(req, &tag, cryptlen, &ops); if (aegis128_do_simd())
ops = &(struct aegis128_ops){
.skcipher_walk_init = skcipher_walk_aead_decrypt,
.crypt_chunk = crypto_aegis128_decrypt_chunk_simd };
crypto_aegis128_crypt(req, &tag, cryptlen, ops);
return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0; return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
} }
...@@ -429,6 +470,9 @@ static struct aead_alg crypto_aegis128_alg = { ...@@ -429,6 +470,9 @@ static struct aead_alg crypto_aegis128_alg = {
static int __init crypto_aegis128_module_init(void) static int __init crypto_aegis128_module_init(void)
{ {
if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD))
have_simd = crypto_aegis128_have_simd();
return crypto_register_aead(&crypto_aegis128_alg); return crypto_register_aead(&crypto_aegis128_alg);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册