summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-07-03 04:55:10 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-07-26 01:03:58 -0400
commit7cdc0ddbf74a19cecb2f0e9efa2cae9d3c665189 (patch)
tree5b44bcb399174e6d64d90ef96e0a80e42350b609
parent521cdde758bf331d4e264ef3deef5a26d5ce0b4f (diff)
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: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/aegis.h14
-rw-r--r--crypto/aegis128-core.c (renamed from crypto/aegis128.c)42
3 files changed, 46 insertions, 11 deletions
diff --git a/crypto/Makefile b/crypto/Makefile
index 93375e124ff7..362a36f0bd2f 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o
90obj-$(CONFIG_CRYPTO_CCM) += ccm.o 90obj-$(CONFIG_CRYPTO_CCM) += ccm.o
91obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o 91obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
92obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o 92obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o
93aegis128-y := aegis128-core.o
93obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o 94obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
94obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o 95obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
95obj-$(CONFIG_CRYPTO_DES) += des_generic.o 96obj-$(CONFIG_CRYPTO_DES) += des_generic.o
diff --git a/crypto/aegis.h b/crypto/aegis.h
index 3308066ddde0..6cb65a497ba2 100644
--- a/crypto/aegis.h
+++ b/crypto/aegis.h
@@ -35,23 +35,23 @@ static const union aegis_block crypto_aegis_const[2] = {
35 } }, 35 } },
36}; 36};
37 37
38static void crypto_aegis_block_xor(union aegis_block *dst, 38static inline void crypto_aegis_block_xor(union aegis_block *dst,
39 const union aegis_block *src) 39 const union aegis_block *src)
40{ 40{
41 dst->words64[0] ^= src->words64[0]; 41 dst->words64[0] ^= src->words64[0];
42 dst->words64[1] ^= src->words64[1]; 42 dst->words64[1] ^= src->words64[1];
43} 43}
44 44
45static void crypto_aegis_block_and(union aegis_block *dst, 45static inline void crypto_aegis_block_and(union aegis_block *dst,
46 const union aegis_block *src) 46 const union aegis_block *src)
47{ 47{
48 dst->words64[0] &= src->words64[0]; 48 dst->words64[0] &= src->words64[0];
49 dst->words64[1] &= src->words64[1]; 49 dst->words64[1] &= src->words64[1];
50} 50}
51 51
52static void crypto_aegis_aesenc(union aegis_block *dst, 52static inline void crypto_aegis_aesenc(union aegis_block *dst,
53 const union aegis_block *src, 53 const union aegis_block *src,
54 const union aegis_block *key) 54 const union aegis_block *key)
55{ 55{
56 const u8 *s = src->bytes; 56 const u8 *s = src->bytes;
57 const u32 *t = crypto_ft_tab[0]; 57 const u32 *t = crypto_ft_tab[0];
diff --git a/crypto/aegis128.c b/crypto/aegis128-core.c
index 32840d5e7f65..f815b4685156 100644
--- a/crypto/aegis128.c
+++ b/crypto/aegis128-core.c
@@ -8,6 +8,7 @@
8 8
9#include <crypto/algapi.h> 9#include <crypto/algapi.h>
10#include <crypto/internal/aead.h> 10#include <crypto/internal/aead.h>
11#include <crypto/internal/simd.h>
11#include <crypto/internal/skcipher.h> 12#include <crypto/internal/skcipher.h>
12#include <crypto/scatterwalk.h> 13#include <crypto/scatterwalk.h>
13#include <linux/err.h> 14#include <linux/err.h>
@@ -15,6 +16,7 @@
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
19#include <asm/simd.h>
18 20
19#include "aegis.h" 21#include "aegis.h"
20 22
@@ -40,6 +42,15 @@ struct aegis128_ops {
40 const u8 *src, unsigned int size); 42 const u8 *src, unsigned int size);
41}; 43};
42 44
45static bool have_simd;
46
47bool crypto_aegis128_have_simd(void);
48void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg);
49void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
50 const u8 *src, unsigned int size);
51void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
52 const u8 *src, unsigned int size);
53
43static void crypto_aegis128_update(struct aegis_state *state) 54static void crypto_aegis128_update(struct aegis_state *state)
44{ 55{
45 union aegis_block tmp; 56 union aegis_block tmp;
@@ -55,12 +66,22 @@ static void crypto_aegis128_update(struct aegis_state *state)
55static void crypto_aegis128_update_a(struct aegis_state *state, 66static void crypto_aegis128_update_a(struct aegis_state *state,
56 const union aegis_block *msg) 67 const union aegis_block *msg)
57{ 68{
69 if (have_simd && crypto_simd_usable()) {
70 crypto_aegis128_update_simd(state, msg);
71 return;
72 }
73
58 crypto_aegis128_update(state); 74 crypto_aegis128_update(state);
59 crypto_aegis_block_xor(&state->blocks[0], msg); 75 crypto_aegis_block_xor(&state->blocks[0], msg);
60} 76}
61 77
62static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg) 78static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg)
63{ 79{
80 if (have_simd && crypto_simd_usable()) {
81 crypto_aegis128_update_simd(state, msg);
82 return;
83 }
84
64 crypto_aegis128_update(state); 85 crypto_aegis128_update(state);
65 crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE); 86 crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE);
66} 87}
@@ -365,7 +386,7 @@ static void crypto_aegis128_crypt(struct aead_request *req,
365 386
366static int crypto_aegis128_encrypt(struct aead_request *req) 387static int crypto_aegis128_encrypt(struct aead_request *req)
367{ 388{
368 static const struct aegis128_ops ops = { 389 const struct aegis128_ops *ops = &(struct aegis128_ops){
369 .skcipher_walk_init = skcipher_walk_aead_encrypt, 390 .skcipher_walk_init = skcipher_walk_aead_encrypt,
370 .crypt_chunk = crypto_aegis128_encrypt_chunk, 391 .crypt_chunk = crypto_aegis128_encrypt_chunk,
371 }; 392 };
@@ -375,7 +396,12 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
375 unsigned int authsize = crypto_aead_authsize(tfm); 396 unsigned int authsize = crypto_aead_authsize(tfm);
376 unsigned int cryptlen = req->cryptlen; 397 unsigned int cryptlen = req->cryptlen;
377 398
378 crypto_aegis128_crypt(req, &tag, cryptlen, &ops); 399 if (have_simd && crypto_simd_usable())
400 ops = &(struct aegis128_ops){
401 .skcipher_walk_init = skcipher_walk_aead_encrypt,
402 .crypt_chunk = crypto_aegis128_encrypt_chunk_simd };
403
404 crypto_aegis128_crypt(req, &tag, cryptlen, ops);
379 405
380 scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen, 406 scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
381 authsize, 1); 407 authsize, 1);
@@ -384,7 +410,7 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
384 410
385static int crypto_aegis128_decrypt(struct aead_request *req) 411static int crypto_aegis128_decrypt(struct aead_request *req)
386{ 412{
387 static const struct aegis128_ops ops = { 413 const struct aegis128_ops *ops = &(struct aegis128_ops){
388 .skcipher_walk_init = skcipher_walk_aead_decrypt, 414 .skcipher_walk_init = skcipher_walk_aead_decrypt,
389 .crypt_chunk = crypto_aegis128_decrypt_chunk, 415 .crypt_chunk = crypto_aegis128_decrypt_chunk,
390 }; 416 };
@@ -398,7 +424,12 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
398 scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen, 424 scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
399 authsize, 0); 425 authsize, 0);
400 426
401 crypto_aegis128_crypt(req, &tag, cryptlen, &ops); 427 if (have_simd && crypto_simd_usable())
428 ops = &(struct aegis128_ops){
429 .skcipher_walk_init = skcipher_walk_aead_decrypt,
430 .crypt_chunk = crypto_aegis128_decrypt_chunk_simd };
431
432 crypto_aegis128_crypt(req, &tag, cryptlen, ops);
402 433
403 return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0; 434 return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
404} 435}
@@ -429,6 +460,9 @@ static struct aead_alg crypto_aegis128_alg = {
429 460
430static int __init crypto_aegis128_module_init(void) 461static int __init crypto_aegis128_module_init(void)
431{ 462{
463 if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD))
464 have_simd = crypto_aegis128_have_simd();
465
432 return crypto_register_aead(&crypto_aegis128_alg); 466 return crypto_register_aead(&crypto_aegis128_alg);
433} 467}
434 468