Skip to content

Commit

Permalink
crypto: aegis128 - add support for SIMD acceleration
Browse files Browse the repository at this point in the history
Add some plumbing to allow the AEGIS128 code to be built with SIMD
routines for acceleration.

Reviewed-by: Ondrej Mosnacek <[email protected]>
Signed-off-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
Ard Biesheuvel authored and herbertx committed Aug 15, 2019
1 parent 8083b1b commit cf3d41a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
1 change: 1 addition & 0 deletions crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o
obj-$(CONFIG_CRYPTO_CCM) += ccm.o
obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o
aegis128-y := aegis128-core.o
obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
obj-$(CONFIG_CRYPTO_DES) += des_generic.o
Expand Down
52 changes: 48 additions & 4 deletions crypto/aegis128.c → crypto/aegis128-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <crypto/algapi.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/simd.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
Expand All @@ -16,6 +17,8 @@
#include <linux/module.h>
#include <linux/scatterlist.h>

#include <asm/simd.h>

#include "aegis.h"

#define AEGIS128_NONCE_SIZE 16
Expand All @@ -40,6 +43,24 @@ struct aegis128_ops {
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)
{
union aegis_block tmp;
Expand All @@ -55,12 +76,22 @@ static void crypto_aegis128_update(struct aegis_state *state)
static void crypto_aegis128_update_a(struct aegis_state *state,
const union aegis_block *msg)
{
if (aegis128_do_simd()) {
crypto_aegis128_update_simd(state, msg);
return;
}

crypto_aegis128_update(state);
crypto_aegis_block_xor(&state->blocks[0], 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_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE);
}
Expand Down Expand Up @@ -365,7 +396,7 @@ static void crypto_aegis128_crypt(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,
.crypt_chunk = crypto_aegis128_encrypt_chunk,
};
Expand All @@ -375,7 +406,12 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
unsigned int authsize = crypto_aead_authsize(tfm);
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,
authsize, 1);
Expand All @@ -384,7 +420,7 @@ static int crypto_aegis128_encrypt(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,
.crypt_chunk = crypto_aegis128_decrypt_chunk,
};
Expand All @@ -398,7 +434,12 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
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;
}
Expand Down Expand Up @@ -429,6 +470,9 @@ static struct aead_alg crypto_aegis128_alg = {

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);
}

Expand Down

0 comments on commit cf3d41a

Please sign in to comment.