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>