Annotation of embedaddon/bird/lib/sha256.c, revision 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>