diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-04-09 06:55:43 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-10 09:39:45 -0400 |
commit | 9205b94923213ee164d7398fdc90826e463c281a (patch) | |
tree | 4391d6b50ba266a9538dac2f8eba5f9d18370c38 | |
parent | b59e2ae3690c8ef5f8ddeeb0b6b3313521b915e6 (diff) |
crypto: arm/sha2-ce - move SHA-224/256 ARMv8 implementation to base layer
This removes all the boilerplate from the existing implementation,
and replaces it with calls into the base layer.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | arch/arm/crypto/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/crypto/sha2-ce-core.S | 19 | ||||
-rw-r--r-- | arch/arm/crypto/sha2-ce-glue.c | 155 |
3 files changed, 39 insertions, 137 deletions
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig index 5ed98bc6f95d..a267529d9577 100644 --- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig | |||
@@ -39,7 +39,7 @@ config CRYPTO_SHA1_ARM_CE | |||
39 | config CRYPTO_SHA2_ARM_CE | 39 | config CRYPTO_SHA2_ARM_CE |
40 | tristate "SHA-224/256 digest algorithm (ARM v8 Crypto Extensions)" | 40 | tristate "SHA-224/256 digest algorithm (ARM v8 Crypto Extensions)" |
41 | depends on KERNEL_MODE_NEON | 41 | depends on KERNEL_MODE_NEON |
42 | select CRYPTO_SHA256 | 42 | select CRYPTO_SHA256_ARM |
43 | select CRYPTO_HASH | 43 | select CRYPTO_HASH |
44 | help | 44 | help |
45 | SHA-256 secure hash standard (DFIPS 180-2) implemented | 45 | SHA-256 secure hash standard (DFIPS 180-2) implemented |
diff --git a/arch/arm/crypto/sha2-ce-core.S b/arch/arm/crypto/sha2-ce-core.S index 96af09fe957b..87ec11a5f405 100644 --- a/arch/arm/crypto/sha2-ce-core.S +++ b/arch/arm/crypto/sha2-ce-core.S | |||
@@ -69,27 +69,18 @@ | |||
69 | .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | 69 | .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * void sha2_ce_transform(int blocks, u8 const *src, u32 *state, | 72 | * void sha2_ce_transform(struct sha256_state *sst, u8 const *src, |
73 | * u8 *head); | 73 | int blocks); |
74 | */ | 74 | */ |
75 | ENTRY(sha2_ce_transform) | 75 | ENTRY(sha2_ce_transform) |
76 | /* load state */ | 76 | /* load state */ |
77 | vld1.32 {dga-dgb}, [r2] | 77 | vld1.32 {dga-dgb}, [r0] |
78 | |||
79 | /* load partial input (if supplied) */ | ||
80 | teq r3, #0 | ||
81 | beq 0f | ||
82 | vld1.32 {q0-q1}, [r3]! | ||
83 | vld1.32 {q2-q3}, [r3] | ||
84 | teq r0, #0 | ||
85 | b 1f | ||
86 | 78 | ||
87 | /* load input */ | 79 | /* load input */ |
88 | 0: vld1.32 {q0-q1}, [r1]! | 80 | 0: vld1.32 {q0-q1}, [r1]! |
89 | vld1.32 {q2-q3}, [r1]! | 81 | vld1.32 {q2-q3}, [r1]! |
90 | subs r0, r0, #1 | 82 | subs r2, r2, #1 |
91 | 83 | ||
92 | 1: | ||
93 | #ifndef CONFIG_CPU_BIG_ENDIAN | 84 | #ifndef CONFIG_CPU_BIG_ENDIAN |
94 | vrev32.8 q0, q0 | 85 | vrev32.8 q0, q0 |
95 | vrev32.8 q1, q1 | 86 | vrev32.8 q1, q1 |
@@ -129,6 +120,6 @@ ENTRY(sha2_ce_transform) | |||
129 | bne 0b | 120 | bne 0b |
130 | 121 | ||
131 | /* store new state */ | 122 | /* store new state */ |
132 | vst1.32 {dga-dgb}, [r2] | 123 | vst1.32 {dga-dgb}, [r0] |
133 | bx lr | 124 | bx lr |
134 | ENDPROC(sha2_ce_transform) | 125 | ENDPROC(sha2_ce_transform) |
diff --git a/arch/arm/crypto/sha2-ce-glue.c b/arch/arm/crypto/sha2-ce-glue.c index 0449eca3aab3..0755b2d657f3 100644 --- a/arch/arm/crypto/sha2-ce-glue.c +++ b/arch/arm/crypto/sha2-ce-glue.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <crypto/internal/hash.h> | 11 | #include <crypto/internal/hash.h> |
12 | #include <crypto/sha.h> | 12 | #include <crypto/sha.h> |
13 | #include <crypto/sha256_base.h> | ||
13 | #include <linux/crypto.h> | 14 | #include <linux/crypto.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | 16 | ||
@@ -18,148 +19,60 @@ | |||
18 | #include <asm/neon.h> | 19 | #include <asm/neon.h> |
19 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
20 | 21 | ||
22 | #include "sha256_glue.h" | ||
23 | |||
21 | MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions"); | 24 | MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions"); |
22 | MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); | 25 | MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); |
23 | MODULE_LICENSE("GPL v2"); | 26 | MODULE_LICENSE("GPL v2"); |
24 | 27 | ||
25 | asmlinkage void sha2_ce_transform(int blocks, u8 const *src, u32 *state, | 28 | asmlinkage void sha2_ce_transform(struct sha256_state *sst, u8 const *src, |
26 | u8 *head); | 29 | int blocks); |
27 | 30 | ||
28 | static int sha224_init(struct shash_desc *desc) | 31 | static int sha2_ce_update(struct shash_desc *desc, const u8 *data, |
32 | unsigned int len) | ||
29 | { | 33 | { |
30 | struct sha256_state *sctx = shash_desc_ctx(desc); | 34 | struct sha256_state *sctx = shash_desc_ctx(desc); |
31 | 35 | ||
32 | *sctx = (struct sha256_state){ | 36 | if (!may_use_simd() || |
33 | .state = { | 37 | (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE) |
34 | SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3, | 38 | return crypto_sha256_arm_update(desc, data, len); |
35 | SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7, | ||
36 | } | ||
37 | }; | ||
38 | return 0; | ||
39 | } | ||
40 | 39 | ||
41 | static int sha256_init(struct shash_desc *desc) | 40 | kernel_neon_begin(); |
42 | { | 41 | sha256_base_do_update(desc, data, len, |
43 | struct sha256_state *sctx = shash_desc_ctx(desc); | 42 | (sha256_block_fn *)sha2_ce_transform); |
43 | kernel_neon_end(); | ||
44 | 44 | ||
45 | *sctx = (struct sha256_state){ | ||
46 | .state = { | ||
47 | SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, | ||
48 | SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7, | ||
49 | } | ||
50 | }; | ||
51 | return 0; | 45 | return 0; |
52 | } | 46 | } |
53 | 47 | ||
54 | static int sha2_update(struct shash_desc *desc, const u8 *data, | 48 | static int sha2_ce_finup(struct shash_desc *desc, const u8 *data, |
55 | unsigned int len) | 49 | unsigned int len, u8 *out) |
56 | { | 50 | { |
57 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
58 | unsigned int partial; | ||
59 | |||
60 | if (!may_use_simd()) | 51 | if (!may_use_simd()) |
61 | return crypto_sha256_update(desc, data, len); | 52 | return crypto_sha256_arm_finup(desc, data, len, out); |
62 | |||
63 | partial = sctx->count % SHA256_BLOCK_SIZE; | ||
64 | sctx->count += len; | ||
65 | |||
66 | if ((partial + len) >= SHA256_BLOCK_SIZE) { | ||
67 | int blocks; | ||
68 | |||
69 | if (partial) { | ||
70 | int p = SHA256_BLOCK_SIZE - partial; | ||
71 | |||
72 | memcpy(sctx->buf + partial, data, p); | ||
73 | data += p; | ||
74 | len -= p; | ||
75 | } | ||
76 | |||
77 | blocks = len / SHA256_BLOCK_SIZE; | ||
78 | len %= SHA256_BLOCK_SIZE; | ||
79 | 53 | ||
80 | kernel_neon_begin(); | 54 | kernel_neon_begin(); |
81 | sha2_ce_transform(blocks, data, sctx->state, | ||
82 | partial ? sctx->buf : NULL); | ||
83 | kernel_neon_end(); | ||
84 | |||
85 | data += blocks * SHA256_BLOCK_SIZE; | ||
86 | partial = 0; | ||
87 | } | ||
88 | if (len) | 55 | if (len) |
89 | memcpy(sctx->buf + partial, data, len); | 56 | sha256_base_do_update(desc, data, len, |
90 | return 0; | 57 | (sha256_block_fn *)sha2_ce_transform); |
91 | } | 58 | sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform); |
92 | 59 | kernel_neon_end(); | |
93 | static void sha2_final(struct shash_desc *desc) | ||
94 | { | ||
95 | static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, }; | ||
96 | 60 | ||
97 | struct sha256_state *sctx = shash_desc_ctx(desc); | 61 | return sha256_base_finish(desc, out); |
98 | __be64 bits = cpu_to_be64(sctx->count << 3); | ||
99 | u32 padlen = SHA256_BLOCK_SIZE | ||
100 | - ((sctx->count + sizeof(bits)) % SHA256_BLOCK_SIZE); | ||
101 | |||
102 | sha2_update(desc, padding, padlen); | ||
103 | sha2_update(desc, (const u8 *)&bits, sizeof(bits)); | ||
104 | } | 62 | } |
105 | 63 | ||
106 | static int sha224_final(struct shash_desc *desc, u8 *out) | 64 | static int sha2_ce_final(struct shash_desc *desc, u8 *out) |
107 | { | 65 | { |
108 | struct sha256_state *sctx = shash_desc_ctx(desc); | 66 | return sha2_ce_finup(desc, NULL, 0, out); |
109 | __be32 *dst = (__be32 *)out; | ||
110 | int i; | ||
111 | |||
112 | sha2_final(desc); | ||
113 | |||
114 | for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++) | ||
115 | put_unaligned_be32(sctx->state[i], dst++); | ||
116 | |||
117 | *sctx = (struct sha256_state){}; | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static int sha256_final(struct shash_desc *desc, u8 *out) | ||
122 | { | ||
123 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
124 | __be32 *dst = (__be32 *)out; | ||
125 | int i; | ||
126 | |||
127 | sha2_final(desc); | ||
128 | |||
129 | for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++) | ||
130 | put_unaligned_be32(sctx->state[i], dst++); | ||
131 | |||
132 | *sctx = (struct sha256_state){}; | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int sha2_export(struct shash_desc *desc, void *out) | ||
137 | { | ||
138 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
139 | struct sha256_state *dst = out; | ||
140 | |||
141 | *dst = *sctx; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int sha2_import(struct shash_desc *desc, const void *in) | ||
146 | { | ||
147 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
148 | struct sha256_state const *src = in; | ||
149 | |||
150 | *sctx = *src; | ||
151 | return 0; | ||
152 | } | 67 | } |
153 | 68 | ||
154 | static struct shash_alg algs[] = { { | 69 | static struct shash_alg algs[] = { { |
155 | .init = sha224_init, | 70 | .init = sha224_base_init, |
156 | .update = sha2_update, | 71 | .update = sha2_ce_update, |
157 | .final = sha224_final, | 72 | .final = sha2_ce_final, |
158 | .export = sha2_export, | 73 | .finup = sha2_ce_finup, |
159 | .import = sha2_import, | ||
160 | .descsize = sizeof(struct sha256_state), | 74 | .descsize = sizeof(struct sha256_state), |
161 | .digestsize = SHA224_DIGEST_SIZE, | 75 | .digestsize = SHA224_DIGEST_SIZE, |
162 | .statesize = sizeof(struct sha256_state), | ||
163 | .base = { | 76 | .base = { |
164 | .cra_name = "sha224", | 77 | .cra_name = "sha224", |
165 | .cra_driver_name = "sha224-ce", | 78 | .cra_driver_name = "sha224-ce", |
@@ -169,14 +82,12 @@ static struct shash_alg algs[] = { { | |||
169 | .cra_module = THIS_MODULE, | 82 | .cra_module = THIS_MODULE, |
170 | } | 83 | } |
171 | }, { | 84 | }, { |
172 | .init = sha256_init, | 85 | .init = sha256_base_init, |
173 | .update = sha2_update, | 86 | .update = sha2_ce_update, |
174 | .final = sha256_final, | 87 | .final = sha2_ce_final, |
175 | .export = sha2_export, | 88 | .finup = sha2_ce_finup, |
176 | .import = sha2_import, | ||
177 | .descsize = sizeof(struct sha256_state), | 89 | .descsize = sizeof(struct sha256_state), |
178 | .digestsize = SHA256_DIGEST_SIZE, | 90 | .digestsize = SHA256_DIGEST_SIZE, |
179 | .statesize = sizeof(struct sha256_state), | ||
180 | .base = { | 91 | .base = { |
181 | .cra_name = "sha256", | 92 | .cra_name = "sha256", |
182 | .cra_driver_name = "sha256-ce", | 93 | .cra_driver_name = "sha256-ce", |