#include <linux/mm.h>
#include <linux/init.h>
#include <linux/crypto.h>
+#include <linux/types.h>
#include <asm/scatterlist.h>
#include <asm/byteorder.h>
u64 state[8];
u32 count[4];
u8 buf[128];
+ u64 W[80];
};
static inline u64 Ch(u64 x, u64 y, u64 z)
return (x >> y) | (x << (64 - y));
}
-const u64 sha512_K[80] = {
+static const u64 sha512_K[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
static inline void LOAD_OP(int I, u64 *W, const u8 *input)
{
- u64 t1 = input[(8*I) ] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+1] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+2] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+3] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+4] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+5] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+6] & 0xff;
- t1 <<= 8;
- t1 |= input[(8*I)+7] & 0xff;
- W[I] = t1;
+ W[I] = __be64_to_cpu( ((__be64*)(input))[I] );
}
static inline void BLEND_OP(int I, u64 *W)
{
- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+ W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
}
static void
-sha512_transform(u64 *state, const u8 *input)
+sha512_transform(u64 *state, u64 *W, const u8 *input)
{
u64 a, b, c, d, e, f, g, h, t1, t2;
- u64 W[80];
int i;
/* erase our data */
a = b = c = d = e = f = g = h = t1 = t2 = 0;
- memset(W, 0, 80 * sizeof(u64));
}
static void
/* Transform as many times as possible. */
if (len >= part_len) {
memcpy(&sctx->buf[index], data, part_len);
- sha512_transform(sctx->state, sctx->buf);
+ sha512_transform(sctx->state, sctx->W, sctx->buf);
for (i = part_len; i + 127 < len; i+=128)
- sha512_transform(sctx->state, &data[i]);
+ sha512_transform(sctx->state, sctx->W, &data[i]);
index = 0;
} else {
/* Buffer remaining input */
memcpy(&sctx->buf[index], &data[i], len - i);
+
+ /* erase our data */
+ memset(sctx->W, 0, sizeof(sctx->W));
}
static void
sha512_final(void *ctx, u8 *hash)
{
struct sha512_ctx *sctx = ctx;
-
static u8 padding[128] = { 0x80, };
-
- u32 t;
- u64 t2;
- u8 bits[128];
+ __be64 *dst = (__be64 *)hash;
+ __be32 bits[4];
unsigned int index, pad_len;
- int i, j;
-
- index = pad_len = t = i = j = 0;
- t2 = 0;
+ int i;
/* Save number of bits */
- t = sctx->count[0];
- bits[15] = t; t>>=8;
- bits[14] = t; t>>=8;
- bits[13] = t; t>>=8;
- bits[12] = t;
- t = sctx->count[1];
- bits[11] = t; t>>=8;
- bits[10] = t; t>>=8;
- bits[9 ] = t; t>>=8;
- bits[8 ] = t;
- t = sctx->count[2];
- bits[7 ] = t; t>>=8;
- bits[6 ] = t; t>>=8;
- bits[5 ] = t; t>>=8;
- bits[4 ] = t;
- t = sctx->count[3];
- bits[3 ] = t; t>>=8;
- bits[2 ] = t; t>>=8;
- bits[1 ] = t; t>>=8;
- bits[0 ] = t;
+ bits[3] = cpu_to_be32(sctx->count[0]);
+ bits[2] = cpu_to_be32(sctx->count[1]);
+ bits[1] = cpu_to_be32(sctx->count[2]);
+ bits[0] = cpu_to_be32(sctx->count[3]);
/* Pad out to 112 mod 128. */
index = (sctx->count[0] >> 3) & 0x7f;
sha512_update(sctx, padding, pad_len);
/* Append length (before padding) */
- sha512_update(sctx, bits, 16);
+ sha512_update(sctx, (const u8 *)bits, sizeof(bits));
/* Store state in digest */
- for (i = j = 0; i < 8; i++, j += 8) {
- t2 = sctx->state[i];
- hash[j+7] = (char)t2 & 0xff; t2>>=8;
- hash[j+6] = (char)t2 & 0xff; t2>>=8;
- hash[j+5] = (char)t2 & 0xff; t2>>=8;
- hash[j+4] = (char)t2 & 0xff; t2>>=8;
- hash[j+3] = (char)t2 & 0xff; t2>>=8;
- hash[j+2] = (char)t2 & 0xff; t2>>=8;
- hash[j+1] = (char)t2 & 0xff; t2>>=8;
- hash[j ] = (char)t2 & 0xff;
- }
-
+ for (i = 0; i < 8; i++)
+ dst[i] = cpu_to_be64(sctx->state[i]);
+
/* Zeroize sensitive information. */
memset(sctx, 0, sizeof(struct sha512_ctx));
}