diff options
Diffstat (limited to 'arch/arm/crypto/sha256_neon_glue.c')
-rw-r--r-- | arch/arm/crypto/sha256_neon_glue.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/arm/crypto/sha256_neon_glue.c b/arch/arm/crypto/sha256_neon_glue.c new file mode 100644 index 000000000000..39ccd658817e --- /dev/null +++ b/arch/arm/crypto/sha256_neon_glue.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Glue code for the SHA256 Secure Hash Algorithm assembly implementation | ||
3 | * using NEON instructions. | ||
4 | * | ||
5 | * Copyright © 2015 Google Inc. | ||
6 | * | ||
7 | * This file is based on sha512_neon_glue.c: | ||
8 | * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation; either version 2 of the License, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <crypto/internal/hash.h> | ||
18 | #include <linux/cryptohash.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <crypto/sha.h> | ||
22 | #include <crypto/sha256_base.h> | ||
23 | #include <asm/byteorder.h> | ||
24 | #include <asm/simd.h> | ||
25 | #include <asm/neon.h> | ||
26 | |||
27 | #include "sha256_glue.h" | ||
28 | |||
29 | asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data, | ||
30 | unsigned int num_blks); | ||
31 | |||
32 | static int sha256_update(struct shash_desc *desc, const u8 *data, | ||
33 | unsigned int len) | ||
34 | { | ||
35 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
36 | |||
37 | if (!may_use_simd() || | ||
38 | (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE) | ||
39 | return crypto_sha256_arm_update(desc, data, len); | ||
40 | |||
41 | kernel_neon_begin(); | ||
42 | sha256_base_do_update(desc, data, len, | ||
43 | (sha256_block_fn *)sha256_block_data_order_neon); | ||
44 | kernel_neon_end(); | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int sha256_finup(struct shash_desc *desc, const u8 *data, | ||
50 | unsigned int len, u8 *out) | ||
51 | { | ||
52 | if (!may_use_simd()) | ||
53 | return crypto_sha256_arm_finup(desc, data, len, out); | ||
54 | |||
55 | kernel_neon_begin(); | ||
56 | if (len) | ||
57 | sha256_base_do_update(desc, data, len, | ||
58 | (sha256_block_fn *)sha256_block_data_order_neon); | ||
59 | sha256_base_do_finalize(desc, | ||
60 | (sha256_block_fn *)sha256_block_data_order_neon); | ||
61 | kernel_neon_end(); | ||
62 | |||
63 | return sha256_base_finish(desc, out); | ||
64 | } | ||
65 | |||
66 | static int sha256_final(struct shash_desc *desc, u8 *out) | ||
67 | { | ||
68 | return sha256_finup(desc, NULL, 0, out); | ||
69 | } | ||
70 | |||
71 | struct shash_alg sha256_neon_algs[] = { { | ||
72 | .digestsize = SHA256_DIGEST_SIZE, | ||
73 | .init = sha256_base_init, | ||
74 | .update = sha256_update, | ||
75 | .final = sha256_final, | ||
76 | .finup = sha256_finup, | ||
77 | .descsize = sizeof(struct sha256_state), | ||
78 | .base = { | ||
79 | .cra_name = "sha256", | ||
80 | .cra_driver_name = "sha256-neon", | ||
81 | .cra_priority = 250, | ||
82 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
83 | .cra_blocksize = SHA256_BLOCK_SIZE, | ||
84 | .cra_module = THIS_MODULE, | ||
85 | } | ||
86 | }, { | ||
87 | .digestsize = SHA224_DIGEST_SIZE, | ||
88 | .init = sha224_base_init, | ||
89 | .update = sha256_update, | ||
90 | .final = sha256_final, | ||
91 | .finup = sha256_finup, | ||
92 | .descsize = sizeof(struct sha256_state), | ||
93 | .base = { | ||
94 | .cra_name = "sha224", | ||
95 | .cra_driver_name = "sha224-neon", | ||
96 | .cra_priority = 250, | ||
97 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
98 | .cra_blocksize = SHA224_BLOCK_SIZE, | ||
99 | .cra_module = THIS_MODULE, | ||
100 | } | ||
101 | } }; | ||