| /* |
| * SHA-1 implementation optimized for ARM |
| * |
| * Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org> |
| * Created: September 17, 2005 |
| */ |
| |
| #include <string.h> |
| #include "sha1.h" |
| |
| extern void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W); |
| |
| void SHA1_Init(SHA_CTX *c) |
| { |
| c->len = 0; |
| c->hash[0] = 0x67452301; |
| c->hash[1] = 0xefcdab89; |
| c->hash[2] = 0x98badcfe; |
| c->hash[3] = 0x10325476; |
| c->hash[4] = 0xc3d2e1f0; |
| } |
| |
| void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n) |
| { |
| uint32_t workspace[80]; |
| unsigned int partial; |
| unsigned long done; |
| |
| partial = c->len & 0x3f; |
| c->len += n; |
| if ((partial + n) >= 64) { |
| if (partial) { |
| done = 64 - partial; |
| memcpy(c->buffer + partial, p, done); |
| sha_transform(c->hash, c->buffer, workspace); |
| partial = 0; |
| } else |
| done = 0; |
| while (n >= done + 64) { |
| sha_transform(c->hash, p + done, workspace); |
| done += 64; |
| } |
| } else |
| done = 0; |
| if (n - done) |
| memcpy(c->buffer + partial, p + done, n - done); |
| } |
| |
| void SHA1_Final(unsigned char *hash, SHA_CTX *c) |
| { |
| uint64_t bitlen; |
| uint32_t bitlen_hi, bitlen_lo; |
| unsigned int i, offset, padlen; |
| unsigned char bits[8]; |
| static const unsigned char padding[64] = { 0x80, }; |
| |
| bitlen = c->len << 3; |
| offset = c->len & 0x3f; |
| padlen = ((offset < 56) ? 56 : (64 + 56)) - offset; |
| SHA1_Update(c, padding, padlen); |
| |
| bitlen_hi = bitlen >> 32; |
| bitlen_lo = bitlen & 0xffffffff; |
| bits[0] = bitlen_hi >> 24; |
| bits[1] = bitlen_hi >> 16; |
| bits[2] = bitlen_hi >> 8; |
| bits[3] = bitlen_hi; |
| bits[4] = bitlen_lo >> 24; |
| bits[5] = bitlen_lo >> 16; |
| bits[6] = bitlen_lo >> 8; |
| bits[7] = bitlen_lo; |
| SHA1_Update(c, bits, 8); |
| |
| for (i = 0; i < 5; i++) { |
| uint32_t v = c->hash[i]; |
| hash[0] = v >> 24; |
| hash[1] = v >> 16; |
| hash[2] = v >> 8; |
| hash[3] = v; |
| hash += 4; |
| } |
| } |