better standard compliance
[rofl0r-kripto.git] / lib / hash / sha1.c
blobf881723fc7b59c4094a1580f908eee76f4eebe8d
1 /*
2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 #include <stdint.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <limits.h>
19 #include <assert.h>
21 #include <kripto/cast.h>
22 #include <kripto/loadstore.h>
23 #include <kripto/rotate.h>
24 #include <kripto/memwipe.h>
25 #include <kripto/hash.h>
26 #include <kripto/desc/hash.h>
27 #include <kripto/object/hash.h>
29 #include <kripto/hash/sha1.h>
31 struct kripto_hash
33 struct kripto_hash_object obj;
34 uint64_t len;
35 uint32_t h[5];
36 uint8_t buf[64];
37 unsigned int i;
38 int o;
41 #define F0(X, Y, Z) (Z ^ (X & (Y ^ Z)))
42 #define F1(X, Y, Z) (X ^ Y ^ Z)
43 #define F2(X, Y, Z) ((X & Y) | (Z & (X | Y)))
45 #define G0(A, B, C, D, E, W) \
46 { \
47 E += ROL32(A, 5) + F0(B, C, D) + W + 0x5A827999; \
48 B = ROL32(B, 30); \
51 #define G1(A, B, C, D, E, W) \
52 { \
53 E += ROL32(A, 5) + F1(B, C, D) + W + 0x6ED9EBA1; \
54 B = ROL32(B, 30); \
57 #define G2(A, B, C, D, E, W) \
58 { \
59 E += ROL32(A, 5) + F2(B, C, D) + W + 0x8F1BBCDC; \
60 B = ROL32(B, 30); \
63 #define G3(A, B, C, D, E, W) \
64 { \
65 E += ROL32(A, 5) + F1(B, C, D) + W + 0xCA62C1D6; \
66 B = ROL32(B, 30); \
69 static kripto_hash *sha1_recreate
71 kripto_hash *s,
72 unsigned int r,
73 size_t len
76 (void)r;
77 (void)len;
78 s->len = s->o = s->i = 0;
80 s->h[0] = 0x67452301;
81 s->h[1] = 0xEFCDAB89;
82 s->h[2] = 0x98BADCFE;
83 s->h[3] = 0x10325476;
84 s->h[4] = 0xC3D2E1F0;
86 return s;
89 static void sha1_process(kripto_hash *s, const uint8_t *data)
91 uint32_t a = s->h[0];
92 uint32_t b = s->h[1];
93 uint32_t c = s->h[2];
94 uint32_t d = s->h[3];
95 uint32_t e = s->h[4];
96 uint32_t w[80];
97 unsigned int i;
99 w[0] = LOAD32B(data);
100 w[1] = LOAD32B(data + 4);
101 w[2] = LOAD32B(data + 8);
102 w[3] = LOAD32B(data + 12);
103 w[4] = LOAD32B(data + 16);
104 w[5] = LOAD32B(data + 20);
105 w[6] = LOAD32B(data + 24);
106 w[7] = LOAD32B(data + 28);
107 w[8] = LOAD32B(data + 32);
108 w[9] = LOAD32B(data + 36);
109 w[10] = LOAD32B(data + 40);
110 w[11] = LOAD32B(data + 44);
111 w[12] = LOAD32B(data + 48);
112 w[13] = LOAD32B(data + 52);
113 w[14] = LOAD32B(data + 56);
114 w[15] = LOAD32B(data + 60);
116 for(i = 16; i < 80; i++)
117 w[i] = ROL32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
119 for(i = 0; i < 20;)
121 G0(a, b, c, d, e, w[i++]);
122 G0(e, a, b, c, d, w[i++]);
123 G0(d, e, a, b, c, w[i++]);
124 G0(c, d, e, a, b, w[i++]);
125 G0(b, c, d, e, a, w[i++]);
128 while(i < 40)
130 G1(a, b, c, d, e, w[i++]);
131 G1(e, a, b, c, d, w[i++]);
132 G1(d, e, a, b, c, w[i++]);
133 G1(c, d, e, a, b, w[i++]);
134 G1(b, c, d, e, a, w[i++]);
137 while(i < 60)
139 G2(a, b, c, d, e, w[i++]);
140 G2(e, a, b, c, d, w[i++]);
141 G2(d, e, a, b, c, w[i++]);
142 G2(c, d, e, a, b, w[i++]);
143 G2(b, c, d, e, a, w[i++]);
146 while(i < 80)
148 G3(a, b, c, d, e, w[i++]);
149 G3(e, a, b, c, d, w[i++]);
150 G3(d, e, a, b, c, w[i++]);
151 G3(c, d, e, a, b, w[i++]);
152 G3(b, c, d, e, a, w[i++]);
155 kripto_memwipe(w, 320);
157 s->h[0] += a;
158 s->h[1] += b;
159 s->h[2] += c;
160 s->h[3] += d;
161 s->h[4] += e;
164 static void sha1_input
166 kripto_hash *s,
167 const void *in,
168 size_t len
171 size_t i;
173 s->len += len << 3;
174 assert(s->len >= len << 3);
176 for(i = 0; i < len; i++)
178 s->buf[s->i++] = CU8(in)[i];
180 if(s->i == 64)
182 sha1_process(s, s->buf);
183 s->i = 0;
188 static void sha1_finish(kripto_hash *s)
190 s->buf[s->i++] = 0x80; /* pad */
192 if(s->i > 56) /* not enough space for length */
194 while(s->i < 64) s->buf[s->i++] = 0;
195 sha1_process(s, s->buf);
196 s->i = 0;
198 while(s->i < 56) s->buf[s->i++] = 0;
200 /* add length */
201 //s->len << 3;
202 STORE64B(s->len, s->buf + 56);
204 sha1_process(s, s->buf);
206 s->i = 0;
207 s->o = -1;
210 static void sha1_output(kripto_hash *s, void *out, size_t len)
212 unsigned int i;
214 if(!s->o) sha1_finish(s);
216 /* big endian */
217 for(i = 0; i < len; s->i++, i++)
218 U8(out)[i] = s->h[s->i >> 2] >> (24 - ((s->i & 3) << 3));
221 static kripto_hash *sha1_create(unsigned int r, size_t len)
223 kripto_hash *s;
225 s = malloc(sizeof(kripto_hash));
226 if(!s) return 0;
228 s->obj.desc = kripto_hash_sha1;
230 (void)sha1_recreate(s, r, len);
232 return s;
235 static void sha1_destroy(kripto_hash *s)
237 kripto_memwipe(s, sizeof(kripto_hash));
238 free(s);
241 static int sha1_hash
243 unsigned int r,
244 const void *in,
245 size_t in_len,
246 void *out,
247 size_t out_len
250 kripto_hash s;
252 (void)sha1_recreate(&s, r, out_len);
253 sha1_input(&s, in, in_len);
254 sha1_output(&s, out, out_len);
256 kripto_memwipe(&s, sizeof(kripto_hash));
258 return 0;
261 static const kripto_hash_desc sha1 =
263 &sha1_create,
264 &sha1_recreate,
265 &sha1_input,
266 &sha1_output,
267 &sha1_destroy,
268 &sha1_hash,
269 20, /* max output */
270 64 /* block_size */
273 const kripto_hash_desc *const kripto_hash_sha1 = &sha1;