summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-08-11 18:59:10 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-08-15 07:52:15 -0400
commitcf3d41adcc3595e7ccfbc9359a5daf39ee07aa8b (patch)
tree7d0bdbfd7c864dd1c22c3338f1cd85bc3892f1dc
parent8083b1bf8163e7ae7d8c90f221106d96450b8aa8 (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/aegis128-core.c (renamed from crypto/aegis128.c)52
2 files changed, 49 insertions, 4 deletions
diff --git a/crypto/Makefile b/crypto/Makefile
index cfcc954e59f9..92e985714ff6 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/aegis128.c b/crypto/aegis128-core.c
index 32840d5e7f65..fa69e99968e2 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>
@@ -16,6 +17,8 @@
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
18 19
20#include <asm/simd.h>
21
19#include "aegis.h" 22#include "aegis.h"
20 23
21#define AEGIS128_NONCE_SIZE 16 24#define AEGIS128_NONCE_SIZE 16
@@ -40,6 +43,24 @@ struct aegis128_ops {
40 const u8 *src, unsigned int size); 43 const u8 *src, unsigned int size);
41}; 44};
42 45
46static bool have_simd;
47
48static bool aegis128_do_simd(void)
49{
50#ifdef CONFIG_CRYPTO_AEGIS128_SIMD
51 if (have_simd)
52 return crypto_simd_usable();
53#endif
54 return false;
55}
56
57bool crypto_aegis128_have_simd(void);
58void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg);
59void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
60 const u8 *src, unsigned int size);
61void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
62 const u8 *src, unsigned int size);
63
43static void crypto_aegis128_update(struct aegis_state *state) 64static void crypto_aegis128_update(struct aegis_state *state)
44{ 65{
45 union aegis_block tmp; 66 union aegis_block tmp;
@@ -55,12 +76,22 @@ static void crypto_aegis128_update(struct aegis_state *state)
55static void crypto_aegis128_update_a(struct aegis_state *state, 76static void crypto_aegis128_update_a(struct aegis_state *state,
56 const union aegis_block *msg) 77 const union aegis_block *msg)
57{ 78{
79 if (aegis128_do_simd()) {
80 crypto_aegis128_update_simd(state, msg);
81 return;
82 }
83
58 crypto_aegis128_update(state); 84 crypto_aegis128_update(state);
59 crypto_aegis_block_xor(&state->blocks[0], msg); 85 crypto_aegis_block_xor(&state->blocks[0], msg);
60} 86}
61 87
62static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg) 88static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg)
63{ 89{
90 if (aegis128_do_simd()) {
91 crypto_aegis128_update_simd(state, msg);
92 return;
93 }
94
64 crypto_aegis128_update(state); 95 crypto_aegis128_update(state);
65 crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE); 96 crypto_xor(state->blocks[0].bytes, msg, AEGIS_BLOCK_SIZE);
66} 97}
@@ -365,7 +396,7 @@ static void crypto_aegis128_crypt(struct aead_request *req,
365 396
366static int crypto_aegis128_encrypt(struct aead_request *req) 397static int crypto_aegis128_encrypt(struct aead_request *req)
367{ 398{
368 static const struct aegis128_ops ops = { 399 const struct aegis128_ops *ops = &(struct aegis128_ops){
369 .skcipher_walk_init = skcipher_walk_aead_encrypt, 400 .skcipher_walk_init = skcipher_walk_aead_encrypt,
370 .crypt_chunk = crypto_aegis128_encrypt_chunk, 401 .crypt_chunk = crypto_aegis128_encrypt_chunk,
371 }; 402 };
@@ -375,7 +406,12 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
375 unsigned int authsize = crypto_aead_authsize(tfm); 406 unsigned int authsize = crypto_aead_authsize(tfm);
376 unsigned int cryptlen = req->cryptlen; 407 unsigned int cryptlen = req->cryptlen;
377 408
378 crypto_aegis128_crypt(req, &tag, cryptlen, &ops); 409 if (aegis128_do_simd())
410 ops = &(struct aegis128_ops){
411 .skcipher_walk_init = skcipher_walk_aead_encrypt,
412 .crypt_chunk = crypto_aegis128_encrypt_chunk_simd };
413
414 crypto_aegis128_crypt(req, &tag, cryptlen, ops);
379 415
380 scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen, 416 scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
381 authsize, 1); 417 authsize, 1);
@@ -384,7 +420,7 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
384 420
385static int crypto_aegis128_decrypt(struct aead_request *req) 421static int crypto_aegis128_decrypt(struct aead_request *req)
386{ 422{
387 static const struct aegis128_ops ops = { 423 const struct aegis128_ops *ops = &(struct aegis128_ops){
388 .skcipher_walk_init = skcipher_walk_aead_decrypt, 424 .skcipher_walk_init = skcipher_walk_aead_decrypt,
389 .crypt_chunk = crypto_aegis128_decrypt_chunk, 425 .crypt_chunk = crypto_aegis128_decrypt_chunk,
390 }; 426 };
@@ -398,7 +434,12 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
398 scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen, 434 scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
399 authsize, 0); 435 authsize, 0);
400 436
401 crypto_aegis128_crypt(req, &tag, cryptlen, &ops); 437 if (aegis128_do_simd())
438 ops = &(struct aegis128_ops){
439 .skcipher_walk_init = skcipher_walk_aead_decrypt,
440 .crypt_chunk = crypto_aegis128_decrypt_chunk_simd };
441
442 crypto_aegis128_crypt(req, &tag, cryptlen, ops);
402 443
403 return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0; 444 return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
404} 445}
@@ -429,6 +470,9 @@ static struct aead_alg crypto_aegis128_alg = {
429 470
430static int __init crypto_aegis128_module_init(void) 471static int __init crypto_aegis128_module_init(void)
431{ 472{
473 if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD))
474 have_simd = crypto_aegis128_have_simd();
475
432 return crypto_register_aead(&crypto_aegis128_alg); 476 return crypto_register_aead(&crypto_aegis128_alg);
433} 477}
434 478