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