diff options
author | Adrian-Ken Rueegsegger <ken@codelabs.ch> | 2008-12-17 00:47:52 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-12-24 19:02:25 -0500 |
commit | f9e2bca6c22d75a289a349f869701214d63b5060 (patch) | |
tree | 083ac49104a185aab02b93328012b46aec5f071a /crypto/sha512_generic.c | |
parent | 19e2bf146759aea38fd6c2daea08cb7a6367149b (diff) |
crypto: sha512 - Move message schedule W[80] to static percpu area
The message schedule W (u64[80]) is too big for the stack. In order
for this algorithm to be used with shash it is moved to a static
percpu area.
Signed-off-by: Adrian-Ken Rueegsegger <ken@codelabs.ch>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/sha512_generic.c')
-rw-r--r-- | crypto/sha512_generic.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index bc3686138aeb..cb85516d3a78 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c | |||
@@ -18,16 +18,17 @@ | |||
18 | #include <linux/crypto.h> | 18 | #include <linux/crypto.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <crypto/sha.h> | 20 | #include <crypto/sha.h> |
21 | 21 | #include <linux/percpu.h> | |
22 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
23 | 23 | ||
24 | struct sha512_ctx { | 24 | struct sha512_ctx { |
25 | u64 state[8]; | 25 | u64 state[8]; |
26 | u32 count[4]; | 26 | u32 count[4]; |
27 | u8 buf[128]; | 27 | u8 buf[128]; |
28 | u64 W[80]; | ||
29 | }; | 28 | }; |
30 | 29 | ||
30 | static DEFINE_PER_CPU(u64[80], msg_schedule); | ||
31 | |||
31 | static inline u64 Ch(u64 x, u64 y, u64 z) | 32 | static inline u64 Ch(u64 x, u64 y, u64 z) |
32 | { | 33 | { |
33 | return z ^ (x & (y ^ z)); | 34 | return z ^ (x & (y ^ z)); |
@@ -89,11 +90,12 @@ static inline void BLEND_OP(int I, u64 *W) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | static void | 92 | static void |
92 | sha512_transform(u64 *state, u64 *W, const u8 *input) | 93 | sha512_transform(u64 *state, const u8 *input) |
93 | { | 94 | { |
94 | u64 a, b, c, d, e, f, g, h, t1, t2; | 95 | u64 a, b, c, d, e, f, g, h, t1, t2; |
95 | 96 | ||
96 | int i; | 97 | int i; |
98 | u64 *W = get_cpu_var(msg_schedule); | ||
97 | 99 | ||
98 | /* load the input */ | 100 | /* load the input */ |
99 | for (i = 0; i < 16; i++) | 101 | for (i = 0; i < 16; i++) |
@@ -132,6 +134,8 @@ sha512_transform(u64 *state, u64 *W, const u8 *input) | |||
132 | 134 | ||
133 | /* erase our data */ | 135 | /* erase our data */ |
134 | a = b = c = d = e = f = g = h = t1 = t2 = 0; | 136 | a = b = c = d = e = f = g = h = t1 = t2 = 0; |
137 | memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); | ||
138 | put_cpu_var(msg_schedule); | ||
135 | } | 139 | } |
136 | 140 | ||
137 | static void | 141 | static void |
@@ -187,10 +191,10 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) | |||
187 | /* Transform as many times as possible. */ | 191 | /* Transform as many times as possible. */ |
188 | if (len >= part_len) { | 192 | if (len >= part_len) { |
189 | memcpy(&sctx->buf[index], data, part_len); | 193 | memcpy(&sctx->buf[index], data, part_len); |
190 | sha512_transform(sctx->state, sctx->W, sctx->buf); | 194 | sha512_transform(sctx->state, sctx->buf); |
191 | 195 | ||
192 | for (i = part_len; i + 127 < len; i+=128) | 196 | for (i = part_len; i + 127 < len; i+=128) |
193 | sha512_transform(sctx->state, sctx->W, &data[i]); | 197 | sha512_transform(sctx->state, &data[i]); |
194 | 198 | ||
195 | index = 0; | 199 | index = 0; |
196 | } else { | 200 | } else { |
@@ -199,9 +203,6 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) | |||
199 | 203 | ||
200 | /* Buffer remaining input */ | 204 | /* Buffer remaining input */ |
201 | memcpy(&sctx->buf[index], &data[i], len - i); | 205 | memcpy(&sctx->buf[index], &data[i], len - i); |
202 | |||
203 | /* erase our data */ | ||
204 | memset(sctx->W, 0, sizeof(sctx->W)); | ||
205 | } | 206 | } |
206 | 207 | ||
207 | static void | 208 | static void |