Annotation of embedaddon/bird/lib/sha256.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Library -- SHA-256 and SHA-224 Hash Functions
3: *
4: * (c) 2015 CZ.NIC z.s.p.o.
5: *
6: * Based on the code from libgcrypt-1.6.0, which is
7: * (c) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
8: *
9: * Can be freely distributed and used under the terms of the GNU GPL.
10: */
11:
12: #include "lib/sha256.h"
13: #include "lib/unaligned.h"
14:
15:
16: // #define SHA256_UNROLLED
17:
18: void
19: sha256_init(struct hash_context *CTX)
20: {
21: struct sha256_context *ctx = (void *) CTX;
22:
23: ctx->h0 = 0x6a09e667;
24: ctx->h1 = 0xbb67ae85;
25: ctx->h2 = 0x3c6ef372;
26: ctx->h3 = 0xa54ff53a;
27: ctx->h4 = 0x510e527f;
28: ctx->h5 = 0x9b05688c;
29: ctx->h6 = 0x1f83d9ab;
30: ctx->h7 = 0x5be0cd19;
31:
32: ctx->nblocks = 0;
33: ctx->count = 0;
34: }
35:
36: void
37: sha224_init(struct hash_context *CTX)
38: {
39: struct sha224_context *ctx = (void *) CTX;
40:
41: ctx->h0 = 0xc1059ed8;
42: ctx->h1 = 0x367cd507;
43: ctx->h2 = 0x3070dd17;
44: ctx->h3 = 0xf70e5939;
45: ctx->h4 = 0xffc00b31;
46: ctx->h5 = 0x68581511;
47: ctx->h6 = 0x64f98fa7;
48: ctx->h7 = 0xbefa4fa4;
49:
50: ctx->nblocks = 0;
51: ctx->count = 0;
52: }
53:
54: /* (4.2) same as SHA-1's F1. */
55: static inline u32
56: f1(u32 x, u32 y, u32 z)
57: {
58: return (z ^ (x & (y ^ z)));
59: }
60:
61: /* (4.3) same as SHA-1's F3 */
62: static inline u32
63: f3(u32 x, u32 y, u32 z)
64: {
65: return ((x & y) | (z & (x|y)));
66: }
67:
68: /* Bitwise rotation of an uint to the right */
69: static inline u32 ror(u32 x, int n)
70: {
71: return ((x >> (n&(32-1))) | (x << ((32-n)&(32-1))));
72: }
73:
74: /* (4.4) */
75: static inline u32
76: sum0(u32 x)
77: {
78: return (ror(x, 2) ^ ror(x, 13) ^ ror(x, 22));
79: }
80:
81: /* (4.5) */
82: static inline u32
83: sum1(u32 x)
84: {
85: return (ror(x, 6) ^ ror(x, 11) ^ ror(x, 25));
86: }
87:
88: /*
89: Transform the message X which consists of 16 32-bit-words. See FIPS
90: 180-2 for details. */
91: #define S0(x) (ror((x), 7) ^ ror((x), 18) ^ ((x) >> 3)) /* (4.6) */
92: #define S1(x) (ror((x), 17) ^ ror((x), 19) ^ ((x) >> 10)) /* (4.7) */
93: #define R(a,b,c,d,e,f,g,h,k,w) \
94: do \
95: { \
96: t1 = (h) + sum1((e)) + f1((e),(f),(g)) + (k) + (w); \
97: t2 = sum0((a)) + f3((a),(b),(c)); \
98: h = g; \
99: g = f; \
100: f = e; \
101: e = d + t1; \
102: d = c; \
103: c = b; \
104: b = a; \
105: a = t1 + t2; \
106: } while (0)
107:
108: /*
109: The SHA-256 core: Transform the message X which consists of 16
110: 32-bit-words. See FIPS 180-2 for details.
111: */
112: static uint
113: sha256_transform(struct sha256_context *ctx, const byte *data)
114: {
115: static const u32 K[64] = {
116: 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
117: 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
118: 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
119: 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
120: 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
121: 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
122: 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
123: 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
124: 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
125: 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
126: 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
127: 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
128: 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
129: 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
130: 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
131: 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
132: };
133:
134: u32 a,b,c,d,e,f,g,h,t1,t2;
135: u32 w[64];
136: int i;
137:
138: a = ctx->h0;
139: b = ctx->h1;
140: c = ctx->h2;
141: d = ctx->h3;
142: e = ctx->h4;
143: f = ctx->h5;
144: g = ctx->h6;
145: h = ctx->h7;
146:
147: for (i = 0; i < 16; i++)
148: w[i] = get_u32(data + i * 4);
149:
150: for (; i < 64; i++)
151: w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
152:
153: for (i = 0; i < 64;)
154: {
155: #ifndef SHA256_UNROLLED
156: R(a,b,c,d,e,f,g,h,K[i],w[i]);
157: i++;
158: #else /* Unrolled */
159: t1 = h + sum1(e) + f1(e, f, g) + K[i] + w[i];
160: t2 = sum0(a) + f3(a, b, c);
161: d += t1;
162: h = t1 + t2;
163:
164: t1 = g + sum1(d) + f1(d, e, f) + K[i+1] + w[i+1];
165: t2 = sum0(h) + f3(h, a, b);
166: c += t1;
167: g = t1 + t2;
168:
169: t1 = f + sum1(c) + f1(c, d, e) + K[i+2] + w[i+2];
170: t2 = sum0(g) + f3(g, h, a);
171: b += t1;
172: f = t1 + t2;
173:
174: t1 = e + sum1(b) + f1(b, c, d) + K[i+3] + w[i+3];
175: t2 = sum0(f) + f3(f, g, h);
176: a += t1;
177: e = t1 + t2;
178:
179: t1 = d + sum1(a) + f1(a, b, c) + K[i+4] + w[i+4];
180: t2 = sum0(e) + f3(e, f, g);
181: h += t1;
182: d = t1 + t2;
183:
184: t1 = c + sum1(h) + f1(h, a, b) + K[i+5] + w[i+5];
185: t2 = sum0(d) + f3(d, e, f);
186: g += t1;
187: c = t1 + t2;
188:
189: t1 = b + sum1(g) + f1(g, h, a) + K[i+6] + w[i+6];
190: t2 = sum0(c) + f3(c, d, e);
191: f += t1;
192: b = t1 + t2;
193:
194: t1 = a + sum1(f) + f1(f, g, h) + K[i+7] + w[i+7];
195: t2 = sum0(b) + f3(b, c, d);
196: e += t1;
197: a = t1 + t2;
198:
199: i += 8;
200: #endif
201: }
202:
203: ctx->h0 += a;
204: ctx->h1 += b;
205: ctx->h2 += c;
206: ctx->h3 += d;
207: ctx->h4 += e;
208: ctx->h5 += f;
209: ctx->h6 += g;
210: ctx->h7 += h;
211:
212: return /*burn_stack*/ 74*4+32;
213: }
214: #undef S0
215: #undef S1
216: #undef R
217:
218: /* Common function to write a chunk of data to the transform function
219: of a hash algorithm. Note that the use of the term "block" does
220: not imply a fixed size block. Note that we explicitly allow to use
221: this function after the context has been finalized; the result does
222: not have any meaning but writing after finalize is sometimes
223: helpful to mitigate timing attacks. */
224: void
225: sha256_update(struct hash_context *CTX, const byte *buf, uint len)
226: {
227: struct sha256_context *ctx = (void *) CTX;
228:
229: if (ctx->count)
230: {
231: /* Fill rest of internal buffer */
232: for (; len && ctx->count < SHA256_BLOCK_SIZE; len--)
233: ctx->buf[ctx->count++] = *buf++;
234:
235: if (ctx->count < SHA256_BLOCK_SIZE)
236: return;
237:
238: /* Process data from internal buffer */
239: sha256_transform(ctx, ctx->buf);
240: ctx->nblocks++;
241: ctx->count = 0;
242: }
243:
244: if (!len)
245: return;
246:
247: /* Process data from input buffer */
248: while (len >= SHA256_BLOCK_SIZE)
249: {
250: sha256_transform(ctx, buf);
251: ctx->nblocks++;
252: buf += SHA256_BLOCK_SIZE;
253: len -= SHA256_BLOCK_SIZE;
254: }
255:
256: /* Copy remaining data to internal buffer */
257: memcpy(ctx->buf, buf, len);
258: ctx->count = len;
259: }
260:
261: /*
262: * The routine finally terminates the computation and returns the digest. The
263: * handle is prepared for a new cycle, but adding bytes to the handle will the
264: * destroy the returned buffer.
265: *
266: * Returns: 32 bytes with the message the digest. 28 bytes for SHA-224.
267: */
268: byte *
269: sha256_final(struct hash_context *CTX)
270: {
271: struct sha256_context *ctx = (void *) CTX;
272: u32 t, th, msb, lsb;
273:
274: sha256_update(CTX, NULL, 0); /* flush */
275:
276: t = ctx->nblocks;
277: th = 0;
278:
279: /* multiply by 64 to make a byte count */
280: lsb = t << 6;
281: msb = (th << 6) | (t >> 26);
282: /* add the count */
283: t = lsb;
284: if ((lsb += ctx->count) < t)
285: msb++;
286: /* multiply by 8 to make a bit count */
287: t = lsb;
288: lsb <<= 3;
289: msb <<= 3;
290: msb |= t >> 29;
291:
292: if (ctx->count < 56)
293: {
294: /* enough room */
295: ctx->buf[ctx->count++] = 0x80; /* pad */
296: while (ctx->count < 56)
297: ctx->buf[ctx->count++] = 0; /* pad */
298: }
299: else
300: {
301: /* need one extra block */
302: ctx->buf[ctx->count++] = 0x80; /* pad character */
303: while (ctx->count < 64)
304: ctx->buf[ctx->count++] = 0;
305: sha256_update(CTX, NULL, 0); /* flush */;
306: memset(ctx->buf, 0, 56 ); /* fill next block with zeroes */
307: }
308:
309: /* append the 64 bit count */
310: put_u32(ctx->buf + 56, msb);
311: put_u32(ctx->buf + 60, lsb);
312: sha256_transform(ctx, ctx->buf);
313:
314: byte *p = ctx->buf;
315: #define X(a) do { put_u32(p, ctx->h##a); p += 4; } while(0)
316: X(0);
317: X(1);
318: X(2);
319: X(3);
320: X(4);
321: X(5);
322: X(6);
323: X(7);
324: #undef X
325:
326: return ctx->buf;
327: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>