Merge branch 'maint-1.6.0' into maint-1.6.1
[git] / arm / sha1.c
1 /*
2  * SHA-1 implementation optimized for ARM
3  *
4  * Copyright:   (C) 2005 by Nicolas Pitre <nico@cam.org>
5  * Created:     September 17, 2005
6  */
7
8 #include <string.h>
9 #include "sha1.h"
10
11 extern void arm_sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
12
13 void arm_SHA1_Init(arm_SHA_CTX *c)
14 {
15         c->len = 0;
16         c->hash[0] = 0x67452301;
17         c->hash[1] = 0xefcdab89;
18         c->hash[2] = 0x98badcfe;
19         c->hash[3] = 0x10325476;
20         c->hash[4] = 0xc3d2e1f0;
21 }
22
23 void arm_SHA1_Update(arm_SHA_CTX *c, const void *p, unsigned long n)
24 {
25         uint32_t workspace[80];
26         unsigned int partial;
27         unsigned long done;
28
29         partial = c->len & 0x3f;
30         c->len += n;
31         if ((partial + n) >= 64) {
32                 if (partial) {
33                         done = 64 - partial;
34                         memcpy(c->buffer + partial, p, done);
35                         arm_sha_transform(c->hash, c->buffer, workspace);
36                         partial = 0;
37                 } else
38                         done = 0;
39                 while (n >= done + 64) {
40                         arm_sha_transform(c->hash, p + done, workspace);
41                         done += 64;
42                 }
43         } else
44                 done = 0;
45         if (n - done)
46                 memcpy(c->buffer + partial, p + done, n - done);
47 }
48
49 void arm_SHA1_Final(unsigned char *hash, arm_SHA_CTX *c)
50 {
51         uint64_t bitlen;
52         uint32_t bitlen_hi, bitlen_lo;
53         unsigned int i, offset, padlen;
54         unsigned char bits[8];
55         static const unsigned char padding[64] = { 0x80, };
56
57         bitlen = c->len << 3;
58         offset = c->len & 0x3f;
59         padlen = ((offset < 56) ? 56 : (64 + 56)) - offset;
60         arm_SHA1_Update(c, padding, padlen);
61
62         bitlen_hi = bitlen >> 32;
63         bitlen_lo = bitlen & 0xffffffff;
64         bits[0] = bitlen_hi >> 24;
65         bits[1] = bitlen_hi >> 16;
66         bits[2] = bitlen_hi >> 8;
67         bits[3] = bitlen_hi;
68         bits[4] = bitlen_lo >> 24;
69         bits[5] = bitlen_lo >> 16;
70         bits[6] = bitlen_lo >> 8;
71         bits[7] = bitlen_lo;
72         arm_SHA1_Update(c, bits, 8);
73
74         for (i = 0; i < 5; i++) {
75                 uint32_t v = c->hash[i];
76                 hash[0] = v >> 24;
77                 hash[1] = v >> 16;
78                 hash[2] = v >> 8;
79                 hash[3] = v;
80                 hash += 4;
81         }
82 }