diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2019-08-11 18:59:10 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-08-15 07:52:15 -0400 |
commit | cf3d41adcc3595e7ccfbc9359a5daf39ee07aa8b (patch) | |
tree | 7d0bdbfd7c864dd1c22c3338f1cd85bc3892f1dc | |
parent | 8083b1bf8163e7ae7d8c90f221106d96450b8aa8 (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/Makefile | 1 | ||||
-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 | |||
90 | obj-$(CONFIG_CRYPTO_CCM) += ccm.o | 90 | obj-$(CONFIG_CRYPTO_CCM) += ccm.o |
91 | obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o | 91 | obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o |
92 | obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o | 92 | obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o |
93 | aegis128-y := aegis128-core.o | ||
93 | obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o | 94 | obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o |
94 | obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o | 95 | obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o |
95 | obj-$(CONFIG_CRYPTO_DES) += des_generic.o | 96 | obj-$(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 | ||
46 | static bool have_simd; | ||
47 | |||
48 | static 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 | |||
57 | bool crypto_aegis128_have_simd(void); | ||
58 | void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg); | ||
59 | void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst, | ||
60 | const u8 *src, unsigned int size); | ||
61 | void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst, | ||
62 | const u8 *src, unsigned int size); | ||
63 | |||
43 | static void crypto_aegis128_update(struct aegis_state *state) | 64 | static 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) | |||
55 | static void crypto_aegis128_update_a(struct aegis_state *state, | 76 | static 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 | ||
62 | static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg) | 88 | static 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 | ||
366 | static int crypto_aegis128_encrypt(struct aead_request *req) | 397 | static 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 | ||
385 | static int crypto_aegis128_decrypt(struct aead_request *req) | 421 | static 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 | ||
430 | static int __init crypto_aegis128_module_init(void) | 471 | static 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 | ||