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 Jul 26, 2019
1 parent 521cdde commit 7cdc0dd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 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
14 changes: 7 additions & 7 deletions crypto/aegis.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@ static const union aegis_block crypto_aegis_const[2] = {
} },
};

static void crypto_aegis_block_xor(union aegis_block *dst,
const union aegis_block *src)
static inline void crypto_aegis_block_xor(union aegis_block *dst,
const union aegis_block *src)
{
dst->words64[0] ^= src->words64[0];
dst->words64[1] ^= src->words64[1];
}

static void crypto_aegis_block_and(union aegis_block *dst,
const union aegis_block *src)
static inline void crypto_aegis_block_and(union aegis_block *dst,
const union aegis_block *src)
{
dst->words64[0] &= src->words64[0];
dst->words64[1] &= src->words64[1];
}

static void crypto_aegis_aesenc(union aegis_block *dst,
const union aegis_block *src,
const union aegis_block *key)
static inline void crypto_aegis_aesenc(union aegis_block *dst,
const union aegis_block *src,
const union aegis_block *key)
{
const u8 *s = src->bytes;
const u32 *t = crypto_ft_tab[0];
Expand Down
42 changes: 38 additions & 4 deletions crypto/aegis128.c → crypto/aegis128-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

#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>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <asm/simd.h>

#include "aegis.h"

Expand All @@ -40,6 +42,15 @@ struct aegis128_ops {
const u8 *src, unsigned int size);
};

static bool have_simd;

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 +66,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 (have_simd && crypto_simd_usable()) {
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 (have_simd && crypto_simd_usable()) {
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 +386,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 +396,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 (have_simd && crypto_simd_usable())
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 +410,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 +424,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 (have_simd && crypto_simd_usable())
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 +460,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 7cdc0dd

Please sign in to comment.