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>
This commit is contained in:
parent
19e2bf1467
commit
f9e2bca6c2
1 changed files with 9 additions and 8 deletions
|
@ -18,16 +18,17 @@
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <crypto/sha.h>
|
#include <crypto/sha.h>
|
||||||
|
#include <linux/percpu.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
struct sha512_ctx {
|
struct sha512_ctx {
|
||||||
u64 state[8];
|
u64 state[8];
|
||||||
u32 count[4];
|
u32 count[4];
|
||||||
u8 buf[128];
|
u8 buf[128];
|
||||||
u64 W[80];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static DEFINE_PER_CPU(u64[80], msg_schedule);
|
||||||
|
|
||||||
static inline u64 Ch(u64 x, u64 y, u64 z)
|
static inline u64 Ch(u64 x, u64 y, u64 z)
|
||||||
{
|
{
|
||||||
return z ^ (x & (y ^ z));
|
return z ^ (x & (y ^ z));
|
||||||
|
@ -89,11 +90,12 @@ static inline void BLEND_OP(int I, u64 *W)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sha512_transform(u64 *state, u64 *W, const u8 *input)
|
sha512_transform(u64 *state, const u8 *input)
|
||||||
{
|
{
|
||||||
u64 a, b, c, d, e, f, g, h, t1, t2;
|
u64 a, b, c, d, e, f, g, h, t1, t2;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
u64 *W = get_cpu_var(msg_schedule);
|
||||||
|
|
||||||
/* load the input */
|
/* load the input */
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
|
@ -132,6 +134,8 @@ sha512_transform(u64 *state, u64 *W, const u8 *input)
|
||||||
|
|
||||||
/* erase our data */
|
/* erase our data */
|
||||||
a = b = c = d = e = f = g = h = t1 = t2 = 0;
|
a = b = c = d = e = f = g = h = t1 = t2 = 0;
|
||||||
|
memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
|
||||||
|
put_cpu_var(msg_schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -187,10 +191,10 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
|
||||||
/* Transform as many times as possible. */
|
/* Transform as many times as possible. */
|
||||||
if (len >= part_len) {
|
if (len >= part_len) {
|
||||||
memcpy(&sctx->buf[index], data, part_len);
|
memcpy(&sctx->buf[index], data, part_len);
|
||||||
sha512_transform(sctx->state, sctx->W, sctx->buf);
|
sha512_transform(sctx->state, sctx->buf);
|
||||||
|
|
||||||
for (i = part_len; i + 127 < len; i+=128)
|
for (i = part_len; i + 127 < len; i+=128)
|
||||||
sha512_transform(sctx->state, sctx->W, &data[i]);
|
sha512_transform(sctx->state, &data[i]);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,9 +203,6 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
|
||||||
|
|
||||||
/* Buffer remaining input */
|
/* Buffer remaining input */
|
||||||
memcpy(&sctx->buf[index], &data[i], len - i);
|
memcpy(&sctx->buf[index], &data[i], len - i);
|
||||||
|
|
||||||
/* erase our data */
|
|
||||||
memset(sctx->W, 0, sizeof(sctx->W));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue