diff options
Diffstat (limited to 'crypto/sha1.c')
| -rw-r--r-- | crypto/sha1.c | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/crypto/sha1.c b/crypto/sha1.c index 4016f3b8ce9b..21571ed35b7e 100644 --- a/crypto/sha1.c +++ b/crypto/sha1.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
| 22 | #include <linux/crypto.h> | 22 | #include <linux/crypto.h> |
| 23 | #include <linux/cryptohash.h> | 23 | #include <linux/cryptohash.h> |
| 24 | #include <linux/types.h> | ||
| 24 | #include <asm/scatterlist.h> | 25 | #include <asm/scatterlist.h> |
| 25 | #include <asm/byteorder.h> | 26 | #include <asm/byteorder.h> |
| 26 | 27 | ||
| @@ -48,23 +49,33 @@ static void sha1_init(void *ctx) | |||
| 48 | static void sha1_update(void *ctx, const u8 *data, unsigned int len) | 49 | static void sha1_update(void *ctx, const u8 *data, unsigned int len) |
| 49 | { | 50 | { |
| 50 | struct sha1_ctx *sctx = ctx; | 51 | struct sha1_ctx *sctx = ctx; |
| 51 | unsigned int i, j; | 52 | unsigned int partial, done; |
| 52 | u32 temp[SHA_WORKSPACE_WORDS]; | 53 | const u8 *src; |
| 53 | 54 | ||
| 54 | j = (sctx->count >> 3) & 0x3f; | 55 | partial = sctx->count & 0x3f; |
| 55 | sctx->count += len << 3; | 56 | sctx->count += len; |
| 57 | done = 0; | ||
| 58 | src = data; | ||
| 56 | 59 | ||
| 57 | if ((j + len) > 63) { | 60 | if ((partial + len) > 63) { |
| 58 | memcpy(&sctx->buffer[j], data, (i = 64-j)); | 61 | u32 temp[SHA_WORKSPACE_WORDS]; |
| 59 | sha_transform(sctx->state, sctx->buffer, temp); | 62 | |
| 60 | for ( ; i + 63 < len; i += 64) { | 63 | if (partial) { |
| 61 | sha_transform(sctx->state, &data[i], temp); | 64 | done = -partial; |
| 65 | memcpy(sctx->buffer + partial, data, done + 64); | ||
| 66 | src = sctx->buffer; | ||
| 62 | } | 67 | } |
| 63 | j = 0; | 68 | |
| 69 | do { | ||
| 70 | sha_transform(sctx->state, src, temp); | ||
| 71 | done += 64; | ||
| 72 | src = data + done; | ||
| 73 | } while (done + 63 < len); | ||
| 74 | |||
| 75 | memset(temp, 0, sizeof(temp)); | ||
| 76 | partial = 0; | ||
| 64 | } | 77 | } |
| 65 | else i = 0; | 78 | memcpy(sctx->buffer + partial, src, len - done); |
| 66 | memset(temp, 0, sizeof(temp)); | ||
| 67 | memcpy(&sctx->buffer[j], &data[i], len - i); | ||
| 68 | } | 79 | } |
| 69 | 80 | ||
| 70 | 81 | ||
| @@ -72,37 +83,24 @@ static void sha1_update(void *ctx, const u8 *data, unsigned int len) | |||
| 72 | static void sha1_final(void* ctx, u8 *out) | 83 | static void sha1_final(void* ctx, u8 *out) |
| 73 | { | 84 | { |
| 74 | struct sha1_ctx *sctx = ctx; | 85 | struct sha1_ctx *sctx = ctx; |
| 75 | u32 i, j, index, padlen; | 86 | __be32 *dst = (__be32 *)out; |
| 76 | u64 t; | 87 | u32 i, index, padlen; |
| 77 | u8 bits[8] = { 0, }; | 88 | __be64 bits; |
| 78 | static const u8 padding[64] = { 0x80, }; | 89 | static const u8 padding[64] = { 0x80, }; |
| 79 | 90 | ||
| 80 | t = sctx->count; | 91 | bits = cpu_to_be64(sctx->count << 3); |
| 81 | bits[7] = 0xff & t; t>>=8; | ||
| 82 | bits[6] = 0xff & t; t>>=8; | ||
| 83 | bits[5] = 0xff & t; t>>=8; | ||
| 84 | bits[4] = 0xff & t; t>>=8; | ||
| 85 | bits[3] = 0xff & t; t>>=8; | ||
| 86 | bits[2] = 0xff & t; t>>=8; | ||
| 87 | bits[1] = 0xff & t; t>>=8; | ||
| 88 | bits[0] = 0xff & t; | ||
| 89 | 92 | ||
| 90 | /* Pad out to 56 mod 64 */ | 93 | /* Pad out to 56 mod 64 */ |
| 91 | index = (sctx->count >> 3) & 0x3f; | 94 | index = sctx->count & 0x3f; |
| 92 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); | 95 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); |
| 93 | sha1_update(sctx, padding, padlen); | 96 | sha1_update(sctx, padding, padlen); |
| 94 | 97 | ||
| 95 | /* Append length */ | 98 | /* Append length */ |
| 96 | sha1_update(sctx, bits, sizeof bits); | 99 | sha1_update(sctx, (const u8 *)&bits, sizeof(bits)); |
| 97 | 100 | ||
| 98 | /* Store state in digest */ | 101 | /* Store state in digest */ |
| 99 | for (i = j = 0; i < 5; i++, j += 4) { | 102 | for (i = 0; i < 5; i++) |
| 100 | u32 t2 = sctx->state[i]; | 103 | dst[i] = cpu_to_be32(sctx->state[i]); |
| 101 | out[j+3] = t2 & 0xff; t2>>=8; | ||
| 102 | out[j+2] = t2 & 0xff; t2>>=8; | ||
| 103 | out[j+1] = t2 & 0xff; t2>>=8; | ||
| 104 | out[j ] = t2 & 0xff; | ||
| 105 | } | ||
| 106 | 104 | ||
| 107 | /* Wipe context */ | 105 | /* Wipe context */ |
| 108 | memset(sctx, 0, sizeof *sctx); | 106 | memset(sctx, 0, sizeof *sctx); |
