1/* public domain sha1 implementation based on rfc3174 and libtomcrypt */
2#include <stdint.h>
3#include <string.h>
4
5#include "../sha1.h"
6
7static uint32_t
8rol(uint32_t n, int k)
9{
10 return (n << k) | (n >> (32 - k));
11}
12#define F0(b, c, d) (d ^ (b & (c ^ d)))
13#define F1(b, c, d) (b ^ c ^ d)
14#define F2(b, c, d) ((b & c) | (d & (b | c)))
15#define F3(b, c, d) (b ^ c ^ d)
16#define G0(a, b, c, d, e, i) \
17 e += rol(a, 5) + F0(b, c, d) + W[i] + 0x5A827999; \
18 b = rol(b, 30)
19#define G1(a, b, c, d, e, i) \
20 e += rol(a, 5) + F1(b, c, d) + W[i] + 0x6ED9EBA1; \
21 b = rol(b, 30)
22#define G2(a, b, c, d, e, i) \
23 e += rol(a, 5) + F2(b, c, d) + W[i] + 0x8F1BBCDC; \
24 b = rol(b, 30)
25#define G3(a, b, c, d, e, i) \
26 e += rol(a, 5) + F3(b, c, d) + W[i] + 0xCA62C1D6; \
27 b = rol(b, 30)
28
29static void
30processblock(struct sha1 *s, const uint8_t *buf)
31{
32 uint32_t W[80], a, b, c, d, e;
33 int i;
34
35 for (i = 0; i < 16; i++) {
36 W[i] = (uint32_t)buf[4 * i] << 24;
37 W[i] |= (uint32_t)buf[4 * i + 1] << 16;
38 W[i] |= (uint32_t)buf[4 * i + 2] << 8;
39 W[i] |= buf[4 * i + 3];
40 }
41 for (; i < 80; i++)
42 W[i] = rol(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
43 a = s->h[0];
44 b = s->h[1];
45 c = s->h[2];
46 d = s->h[3];
47 e = s->h[4];
48 for (i = 0; i < 20;) {
49 G0(a, b, c, d, e, i++);
50 G0(e, a, b, c, d, i++);
51 G0(d, e, a, b, c, i++);
52 G0(c, d, e, a, b, i++);
53 G0(b, c, d, e, a, i++);
54 }
55 while (i < 40) {
56 G1(a, b, c, d, e, i++);
57 G1(e, a, b, c, d, i++);
58 G1(d, e, a, b, c, i++);
59 G1(c, d, e, a, b, i++);
60 G1(b, c, d, e, a, i++);
61 }
62 while (i < 60) {
63 G2(a, b, c, d, e, i++);
64 G2(e, a, b, c, d, i++);
65 G2(d, e, a, b, c, i++);
66 G2(c, d, e, a, b, i++);
67 G2(b, c, d, e, a, i++);
68 }
69 while (i < 80) {
70 G3(a, b, c, d, e, i++);
71 G3(e, a, b, c, d, i++);
72 G3(d, e, a, b, c, i++);
73 G3(c, d, e, a, b, i++);
74 G3(b, c, d, e, a, i++);
75 }
76 s->h[0] += a;
77 s->h[1] += b;
78 s->h[2] += c;
79 s->h[3] += d;
80 s->h[4] += e;
81}
82
83static void
84pad(struct sha1 *s)
85{
86 unsigned r = s->len % 64;
87
88 s->buf[r++] = 0x80;
89 if (r > 56) {
90 memset(s->buf + r, 0, 64 - r);
91 r = 0;
92 processblock(s, s->buf);
93 }
94 memset(s->buf + r, 0, 56 - r);
95 s->len *= 8;
96 s->buf[56] = s->len >> 56;
97 s->buf[57] = s->len >> 48;
98 s->buf[58] = s->len >> 40;
99 s->buf[59] = s->len >> 32;
100 s->buf[60] = s->len >> 24;
101 s->buf[61] = s->len >> 16;
102 s->buf[62] = s->len >> 8;
103 s->buf[63] = s->len;
104 processblock(s, s->buf);
105}
106
107void
108sha1_init(void *ctx)
109{
110 struct sha1 *s = ctx;
111
112 s->len = 0;
113 s->h[0] = 0x67452301;
114 s->h[1] = 0xEFCDAB89;
115 s->h[2] = 0x98BADCFE;
116 s->h[3] = 0x10325476;
117 s->h[4] = 0xC3D2E1F0;
118}
119
120void
121sha1_sum(void *ctx, uint8_t md[SHA1_DIGEST_LENGTH])
122{
123 struct sha1 *s = ctx;
124 int i;
125
126 pad(s);
127 for (i = 0; i < 5; i++) {
128 md[4 * i] = s->h[i] >> 24;
129 md[4 * i + 1] = s->h[i] >> 16;
130 md[4 * i + 2] = s->h[i] >> 8;
131 md[4 * i + 3] = s->h[i];
132 }
133}
134
135void
136sha1_update(void *ctx, const void *m, unsigned long len)
137{
138 struct sha1 *s = ctx;
139 const uint8_t *p = m;
140 unsigned r = s->len % 64;
141
142 s->len += len;
143 if (r) {
144 if (len < 64 - r) {
145 memcpy(s->buf + r, p, len);
146 return;
147 }
148 memcpy(s->buf + r, p, 64 - r);
149 len -= 64 - r;
150 p += 64 - r;
151 processblock(s, s->buf);
152 }
153 for (; len >= 64; len -= 64, p += 64)
154 processblock(s, p);
155 memcpy(s->buf, p, len);
156}